1 //===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements semantic analysis member access expressions. 10 // 11 //===----------------------------------------------------------------------===// 12 #include "clang/Sema/Overload.h" 13 #include "clang/AST/ASTLambda.h" 14 #include "clang/AST/DeclCXX.h" 15 #include "clang/AST/DeclObjC.h" 16 #include "clang/AST/DeclTemplate.h" 17 #include "clang/AST/ExprCXX.h" 18 #include "clang/AST/ExprObjC.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "clang/Sema/Lookup.h" 21 #include "clang/Sema/Scope.h" 22 #include "clang/Sema/ScopeInfo.h" 23 #include "clang/Sema/SemaInternal.h" 24 25 using namespace clang; 26 using namespace sema; 27 28 typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> BaseSet; 29 30 /// Determines if the given class is provably not derived from all of 31 /// the prospective base classes. 32 static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record, 33 const BaseSet &Bases) { 34 auto BaseIsNotInSet = [&Bases](const CXXRecordDecl *Base) { 35 return !Bases.count(Base->getCanonicalDecl()); 36 }; 37 return BaseIsNotInSet(Record) && Record->forallBases(BaseIsNotInSet); 38 } 39 40 enum IMAKind { 41 /// The reference is definitely not an instance member access. 42 IMA_Static, 43 44 /// The reference may be an implicit instance member access. 45 IMA_Mixed, 46 47 /// The reference may be to an instance member, but it might be invalid if 48 /// so, because the context is not an instance method. 49 IMA_Mixed_StaticContext, 50 51 /// The reference may be to an instance member, but it is invalid if 52 /// so, because the context is from an unrelated class. 53 IMA_Mixed_Unrelated, 54 55 /// The reference is definitely an implicit instance member access. 56 IMA_Instance, 57 58 /// The reference may be to an unresolved using declaration. 59 IMA_Unresolved, 60 61 /// The reference is a contextually-permitted abstract member reference. 62 IMA_Abstract, 63 64 /// The reference may be to an unresolved using declaration and the 65 /// context is not an instance method. 66 IMA_Unresolved_StaticContext, 67 68 // The reference refers to a field which is not a member of the containing 69 // class, which is allowed because we're in C++11 mode and the context is 70 // unevaluated. 71 IMA_Field_Uneval_Context, 72 73 /// All possible referrents are instance members and the current 74 /// context is not an instance method. 75 IMA_Error_StaticContext, 76 77 /// All possible referrents are instance members of an unrelated 78 /// class. 79 IMA_Error_Unrelated 80 }; 81 82 /// The given lookup names class member(s) and is not being used for 83 /// an address-of-member expression. Classify the type of access 84 /// according to whether it's possible that this reference names an 85 /// instance member. This is best-effort in dependent contexts; it is okay to 86 /// conservatively answer "yes", in which case some errors will simply 87 /// not be caught until template-instantiation. 88 static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, 89 const LookupResult &R) { 90 assert(!R.empty() && (*R.begin())->isCXXClassMember()); 91 92 DeclContext *DC = SemaRef.getFunctionLevelDeclContext(); 93 94 bool isStaticContext = SemaRef.CXXThisTypeOverride.isNull() && 95 (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic()); 96 97 if (R.isUnresolvableResult()) 98 return isStaticContext ? IMA_Unresolved_StaticContext : IMA_Unresolved; 99 100 // Collect all the declaring classes of instance members we find. 101 bool hasNonInstance = false; 102 bool isField = false; 103 BaseSet Classes; 104 for (NamedDecl *D : R) { 105 // Look through any using decls. 106 D = D->getUnderlyingDecl(); 107 108 if (D->isCXXInstanceMember()) { 109 isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) || 110 isa<IndirectFieldDecl>(D); 111 112 CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext()); 113 Classes.insert(R->getCanonicalDecl()); 114 } else 115 hasNonInstance = true; 116 } 117 118 // If we didn't find any instance members, it can't be an implicit 119 // member reference. 120 if (Classes.empty()) 121 return IMA_Static; 122 123 // C++11 [expr.prim.general]p12: 124 // An id-expression that denotes a non-static data member or non-static 125 // member function of a class can only be used: 126 // (...) 127 // - if that id-expression denotes a non-static data member and it 128 // appears in an unevaluated operand. 129 // 130 // This rule is specific to C++11. However, we also permit this form 131 // in unevaluated inline assembly operands, like the operand to a SIZE. 132 IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false' 133 assert(!AbstractInstanceResult); 134 switch (SemaRef.ExprEvalContexts.back().Context) { 135 case Sema::ExpressionEvaluationContext::Unevaluated: 136 case Sema::ExpressionEvaluationContext::UnevaluatedList: 137 if (isField && SemaRef.getLangOpts().CPlusPlus11) 138 AbstractInstanceResult = IMA_Field_Uneval_Context; 139 break; 140 141 case Sema::ExpressionEvaluationContext::UnevaluatedAbstract: 142 AbstractInstanceResult = IMA_Abstract; 143 break; 144 145 case Sema::ExpressionEvaluationContext::DiscardedStatement: 146 case Sema::ExpressionEvaluationContext::ConstantEvaluated: 147 case Sema::ExpressionEvaluationContext::PotentiallyEvaluated: 148 case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed: 149 break; 150 } 151 152 // If the current context is not an instance method, it can't be 153 // an implicit member reference. 154 if (isStaticContext) { 155 if (hasNonInstance) 156 return IMA_Mixed_StaticContext; 157 158 return AbstractInstanceResult ? AbstractInstanceResult 159 : IMA_Error_StaticContext; 160 } 161 162 CXXRecordDecl *contextClass; 163 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) 164 contextClass = MD->getParent()->getCanonicalDecl(); 165 else 166 contextClass = cast<CXXRecordDecl>(DC); 167 168 // [class.mfct.non-static]p3: 169 // ...is used in the body of a non-static member function of class X, 170 // if name lookup (3.4.1) resolves the name in the id-expression to a 171 // non-static non-type member of some class C [...] 172 // ...if C is not X or a base class of X, the class member access expression 173 // is ill-formed. 174 if (R.getNamingClass() && 175 contextClass->getCanonicalDecl() != 176 R.getNamingClass()->getCanonicalDecl()) { 177 // If the naming class is not the current context, this was a qualified 178 // member name lookup, and it's sufficient to check that we have the naming 179 // class as a base class. 180 Classes.clear(); 181 Classes.insert(R.getNamingClass()->getCanonicalDecl()); 182 } 183 184 // If we can prove that the current context is unrelated to all the 185 // declaring classes, it can't be an implicit member reference (in 186 // which case it's an error if any of those members are selected). 187 if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes)) 188 return hasNonInstance ? IMA_Mixed_Unrelated : 189 AbstractInstanceResult ? AbstractInstanceResult : 190 IMA_Error_Unrelated; 191 192 return (hasNonInstance ? IMA_Mixed : IMA_Instance); 193 } 194 195 /// Diagnose a reference to a field with no object available. 196 static void diagnoseInstanceReference(Sema &SemaRef, 197 const CXXScopeSpec &SS, 198 NamedDecl *Rep, 199 const DeclarationNameInfo &nameInfo) { 200 SourceLocation Loc = nameInfo.getLoc(); 201 SourceRange Range(Loc); 202 if (SS.isSet()) Range.setBegin(SS.getRange().getBegin()); 203 204 // Look through using shadow decls and aliases. 205 Rep = Rep->getUnderlyingDecl(); 206 207 DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext(); 208 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC); 209 CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr; 210 CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext()); 211 212 bool InStaticMethod = Method && Method->isStatic(); 213 bool IsField = isa<FieldDecl>(Rep) || isa<IndirectFieldDecl>(Rep); 214 215 if (IsField && InStaticMethod) 216 // "invalid use of member 'x' in static member function" 217 SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method) 218 << Range << nameInfo.getName(); 219 else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod && 220 !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass)) 221 // Unqualified lookup in a non-static member function found a member of an 222 // enclosing class. 223 SemaRef.Diag(Loc, diag::err_nested_non_static_member_use) 224 << IsField << RepClass << nameInfo.getName() << ContextClass << Range; 225 else if (IsField) 226 SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use) 227 << nameInfo.getName() << Range; 228 else 229 SemaRef.Diag(Loc, diag::err_member_call_without_object) 230 << Range; 231 } 232 233 /// Builds an expression which might be an implicit member expression. 234 ExprResult Sema::BuildPossibleImplicitMemberExpr( 235 const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, 236 const TemplateArgumentListInfo *TemplateArgs, const Scope *S, 237 UnresolvedLookupExpr *AsULE) { 238 switch (ClassifyImplicitMemberAccess(*this, R)) { 239 case IMA_Instance: 240 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S); 241 242 case IMA_Mixed: 243 case IMA_Mixed_Unrelated: 244 case IMA_Unresolved: 245 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false, 246 S); 247 248 case IMA_Field_Uneval_Context: 249 Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use) 250 << R.getLookupNameInfo().getName(); 251 LLVM_FALLTHROUGH; 252 case IMA_Static: 253 case IMA_Abstract: 254 case IMA_Mixed_StaticContext: 255 case IMA_Unresolved_StaticContext: 256 if (TemplateArgs || TemplateKWLoc.isValid()) 257 return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs); 258 return AsULE ? AsULE : BuildDeclarationNameExpr(SS, R, false); 259 260 case IMA_Error_StaticContext: 261 case IMA_Error_Unrelated: 262 diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(), 263 R.getLookupNameInfo()); 264 return ExprError(); 265 } 266 267 llvm_unreachable("unexpected instance member access kind"); 268 } 269 270 /// Determine whether input char is from rgba component set. 271 static bool 272 IsRGBA(char c) { 273 switch (c) { 274 case 'r': 275 case 'g': 276 case 'b': 277 case 'a': 278 return true; 279 default: 280 return false; 281 } 282 } 283 284 // OpenCL v1.1, s6.1.7 285 // The component swizzle length must be in accordance with the acceptable 286 // vector sizes. 287 static bool IsValidOpenCLComponentSwizzleLength(unsigned len) 288 { 289 return (len >= 1 && len <= 4) || len == 8 || len == 16; 290 } 291 292 /// Check an ext-vector component access expression. 293 /// 294 /// VK should be set in advance to the value kind of the base 295 /// expression. 296 static QualType 297 CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK, 298 SourceLocation OpLoc, const IdentifierInfo *CompName, 299 SourceLocation CompLoc) { 300 // FIXME: Share logic with ExtVectorElementExpr::containsDuplicateElements, 301 // see FIXME there. 302 // 303 // FIXME: This logic can be greatly simplified by splitting it along 304 // halving/not halving and reworking the component checking. 305 const ExtVectorType *vecType = baseType->getAs<ExtVectorType>(); 306 307 // The vector accessor can't exceed the number of elements. 308 const char *compStr = CompName->getNameStart(); 309 310 // This flag determines whether or not the component is one of the four 311 // special names that indicate a subset of exactly half the elements are 312 // to be selected. 313 bool HalvingSwizzle = false; 314 315 // This flag determines whether or not CompName has an 's' char prefix, 316 // indicating that it is a string of hex values to be used as vector indices. 317 bool HexSwizzle = (*compStr == 's' || *compStr == 'S') && compStr[1]; 318 319 bool HasRepeated = false; 320 bool HasIndex[16] = {}; 321 322 int Idx; 323 324 // Check that we've found one of the special components, or that the component 325 // names must come from the same set. 326 if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") || 327 !strcmp(compStr, "even") || !strcmp(compStr, "odd")) { 328 HalvingSwizzle = true; 329 } else if (!HexSwizzle && 330 (Idx = vecType->getPointAccessorIdx(*compStr)) != -1) { 331 bool HasRGBA = IsRGBA(*compStr); 332 do { 333 // Ensure that xyzw and rgba components don't intermingle. 334 if (HasRGBA != IsRGBA(*compStr)) 335 break; 336 if (HasIndex[Idx]) HasRepeated = true; 337 HasIndex[Idx] = true; 338 compStr++; 339 } while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1); 340 341 // Emit a warning if an rgba selector is used earlier than OpenCL C 3.0. 342 if (HasRGBA || (*compStr && IsRGBA(*compStr))) { 343 if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion < 300) { 344 const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr; 345 S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector) 346 << StringRef(DiagBegin, 1) << SourceRange(CompLoc); 347 } 348 } 349 } else { 350 if (HexSwizzle) compStr++; 351 while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) { 352 if (HasIndex[Idx]) HasRepeated = true; 353 HasIndex[Idx] = true; 354 compStr++; 355 } 356 } 357 358 if (!HalvingSwizzle && *compStr) { 359 // We didn't get to the end of the string. This means the component names 360 // didn't come from the same set *or* we encountered an illegal name. 361 S.Diag(OpLoc, diag::err_ext_vector_component_name_illegal) 362 << StringRef(compStr, 1) << SourceRange(CompLoc); 363 return QualType(); 364 } 365 366 // Ensure no component accessor exceeds the width of the vector type it 367 // operates on. 368 if (!HalvingSwizzle) { 369 compStr = CompName->getNameStart(); 370 371 if (HexSwizzle) 372 compStr++; 373 374 while (*compStr) { 375 if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) { 376 S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length) 377 << baseType << SourceRange(CompLoc); 378 return QualType(); 379 } 380 } 381 } 382 383 // OpenCL mode requires swizzle length to be in accordance with accepted 384 // sizes. Clang however supports arbitrary lengths for other languages. 385 if (S.getLangOpts().OpenCL && !HalvingSwizzle) { 386 unsigned SwizzleLength = CompName->getLength(); 387 388 if (HexSwizzle) 389 SwizzleLength--; 390 391 if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) { 392 S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length) 393 << SwizzleLength << SourceRange(CompLoc); 394 return QualType(); 395 } 396 } 397 398 // The component accessor looks fine - now we need to compute the actual type. 399 // The vector type is implied by the component accessor. For example, 400 // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc. 401 // vec4.s0 is a float, vec4.s23 is a vec3, etc. 402 // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2. 403 unsigned CompSize = HalvingSwizzle ? (vecType->getNumElements() + 1) / 2 404 : CompName->getLength(); 405 if (HexSwizzle) 406 CompSize--; 407 408 if (CompSize == 1) 409 return vecType->getElementType(); 410 411 if (HasRepeated) 412 VK = VK_PRValue; 413 414 QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize); 415 // Now look up the TypeDefDecl from the vector type. Without this, 416 // diagostics look bad. We want extended vector types to appear built-in. 417 for (Sema::ExtVectorDeclsType::iterator 418 I = S.ExtVectorDecls.begin(S.getExternalSource()), 419 E = S.ExtVectorDecls.end(); 420 I != E; ++I) { 421 if ((*I)->getUnderlyingType() == VT) 422 return S.Context.getTypedefType(*I); 423 } 424 425 return VT; // should never get here (a typedef type should always be found). 426 } 427 428 static Decl *FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl, 429 IdentifierInfo *Member, 430 const Selector &Sel, 431 ASTContext &Context) { 432 if (Member) 433 if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration( 434 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) 435 return PD; 436 if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel)) 437 return OMD; 438 439 for (const auto *I : PDecl->protocols()) { 440 if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, 441 Context)) 442 return D; 443 } 444 return nullptr; 445 } 446 447 static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, 448 IdentifierInfo *Member, 449 const Selector &Sel, 450 ASTContext &Context) { 451 // Check protocols on qualified interfaces. 452 Decl *GDecl = nullptr; 453 for (const auto *I : QIdTy->quals()) { 454 if (Member) 455 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration( 456 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { 457 GDecl = PD; 458 break; 459 } 460 // Also must look for a getter or setter name which uses property syntax. 461 if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) { 462 GDecl = OMD; 463 break; 464 } 465 } 466 if (!GDecl) { 467 for (const auto *I : QIdTy->quals()) { 468 // Search in the protocol-qualifier list of current protocol. 469 GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context); 470 if (GDecl) 471 return GDecl; 472 } 473 } 474 return GDecl; 475 } 476 477 ExprResult 478 Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType, 479 bool IsArrow, SourceLocation OpLoc, 480 const CXXScopeSpec &SS, 481 SourceLocation TemplateKWLoc, 482 NamedDecl *FirstQualifierInScope, 483 const DeclarationNameInfo &NameInfo, 484 const TemplateArgumentListInfo *TemplateArgs) { 485 // Even in dependent contexts, try to diagnose base expressions with 486 // obviously wrong types, e.g.: 487 // 488 // T* t; 489 // t.f; 490 // 491 // In Obj-C++, however, the above expression is valid, since it could be 492 // accessing the 'f' property if T is an Obj-C interface. The extra check 493 // allows this, while still reporting an error if T is a struct pointer. 494 if (!IsArrow) { 495 const PointerType *PT = BaseType->getAs<PointerType>(); 496 if (PT && (!getLangOpts().ObjC || 497 PT->getPointeeType()->isRecordType())) { 498 assert(BaseExpr && "cannot happen with implicit member accesses"); 499 Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) 500 << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange(); 501 return ExprError(); 502 } 503 } 504 505 assert(BaseType->isDependentType() || 506 NameInfo.getName().isDependentName() || 507 isDependentScopeSpecifier(SS)); 508 509 // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr 510 // must have pointer type, and the accessed type is the pointee. 511 return CXXDependentScopeMemberExpr::Create( 512 Context, BaseExpr, BaseType, IsArrow, OpLoc, 513 SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope, 514 NameInfo, TemplateArgs); 515 } 516 517 /// We know that the given qualified member reference points only to 518 /// declarations which do not belong to the static type of the base 519 /// expression. Diagnose the problem. 520 static void DiagnoseQualifiedMemberReference(Sema &SemaRef, 521 Expr *BaseExpr, 522 QualType BaseType, 523 const CXXScopeSpec &SS, 524 NamedDecl *rep, 525 const DeclarationNameInfo &nameInfo) { 526 // If this is an implicit member access, use a different set of 527 // diagnostics. 528 if (!BaseExpr) 529 return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo); 530 531 SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated) 532 << SS.getRange() << rep << BaseType; 533 } 534 535 // Check whether the declarations we found through a nested-name 536 // specifier in a member expression are actually members of the base 537 // type. The restriction here is: 538 // 539 // C++ [expr.ref]p2: 540 // ... In these cases, the id-expression shall name a 541 // member of the class or of one of its base classes. 542 // 543 // So it's perfectly legitimate for the nested-name specifier to name 544 // an unrelated class, and for us to find an overload set including 545 // decls from classes which are not superclasses, as long as the decl 546 // we actually pick through overload resolution is from a superclass. 547 bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, 548 QualType BaseType, 549 const CXXScopeSpec &SS, 550 const LookupResult &R) { 551 CXXRecordDecl *BaseRecord = 552 cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType)); 553 if (!BaseRecord) { 554 // We can't check this yet because the base type is still 555 // dependent. 556 assert(BaseType->isDependentType()); 557 return false; 558 } 559 560 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { 561 // If this is an implicit member reference and we find a 562 // non-instance member, it's not an error. 563 if (!BaseExpr && !(*I)->isCXXInstanceMember()) 564 return false; 565 566 // Note that we use the DC of the decl, not the underlying decl. 567 DeclContext *DC = (*I)->getDeclContext()->getNonTransparentContext(); 568 if (!DC->isRecord()) 569 continue; 570 571 CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl(); 572 if (BaseRecord->getCanonicalDecl() == MemberRecord || 573 !BaseRecord->isProvablyNotDerivedFrom(MemberRecord)) 574 return false; 575 } 576 577 DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS, 578 R.getRepresentativeDecl(), 579 R.getLookupNameInfo()); 580 return true; 581 } 582 583 namespace { 584 585 // Callback to only accept typo corrections that are either a ValueDecl or a 586 // FunctionTemplateDecl and are declared in the current record or, for a C++ 587 // classes, one of its base classes. 588 class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback { 589 public: 590 explicit RecordMemberExprValidatorCCC(const RecordType *RTy) 591 : Record(RTy->getDecl()) { 592 // Don't add bare keywords to the consumer since they will always fail 593 // validation by virtue of not being associated with any decls. 594 WantTypeSpecifiers = false; 595 WantExpressionKeywords = false; 596 WantCXXNamedCasts = false; 597 WantFunctionLikeCasts = false; 598 WantRemainingKeywords = false; 599 } 600 601 bool ValidateCandidate(const TypoCorrection &candidate) override { 602 NamedDecl *ND = candidate.getCorrectionDecl(); 603 // Don't accept candidates that cannot be member functions, constants, 604 // variables, or templates. 605 if (!ND || !(isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND))) 606 return false; 607 608 // Accept candidates that occur in the current record. 609 if (Record->containsDecl(ND)) 610 return true; 611 612 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) { 613 // Accept candidates that occur in any of the current class' base classes. 614 for (const auto &BS : RD->bases()) { 615 if (const RecordType *BSTy = 616 dyn_cast_or_null<RecordType>(BS.getType().getTypePtrOrNull())) { 617 if (BSTy->getDecl()->containsDecl(ND)) 618 return true; 619 } 620 } 621 } 622 623 return false; 624 } 625 626 std::unique_ptr<CorrectionCandidateCallback> clone() override { 627 return std::make_unique<RecordMemberExprValidatorCCC>(*this); 628 } 629 630 private: 631 const RecordDecl *const Record; 632 }; 633 634 } 635 636 static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, 637 Expr *BaseExpr, 638 const RecordType *RTy, 639 SourceLocation OpLoc, bool IsArrow, 640 CXXScopeSpec &SS, bool HasTemplateArgs, 641 SourceLocation TemplateKWLoc, 642 TypoExpr *&TE) { 643 SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange(); 644 RecordDecl *RDecl = RTy->getDecl(); 645 if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) && 646 SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0), 647 diag::err_typecheck_incomplete_tag, 648 BaseRange)) 649 return true; 650 651 if (HasTemplateArgs || TemplateKWLoc.isValid()) { 652 // LookupTemplateName doesn't expect these both to exist simultaneously. 653 QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0); 654 655 bool MOUS; 656 return SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS, 657 TemplateKWLoc); 658 } 659 660 DeclContext *DC = RDecl; 661 if (SS.isSet()) { 662 // If the member name was a qualified-id, look into the 663 // nested-name-specifier. 664 DC = SemaRef.computeDeclContext(SS, false); 665 666 if (SemaRef.RequireCompleteDeclContext(SS, DC)) { 667 SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag) 668 << SS.getRange() << DC; 669 return true; 670 } 671 672 assert(DC && "Cannot handle non-computable dependent contexts in lookup"); 673 674 if (!isa<TypeDecl>(DC)) { 675 SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_nonclass) 676 << DC << SS.getRange(); 677 return true; 678 } 679 } 680 681 // The record definition is complete, now look up the member. 682 SemaRef.LookupQualifiedName(R, DC, SS); 683 684 if (!R.empty()) 685 return false; 686 687 DeclarationName Typo = R.getLookupName(); 688 SourceLocation TypoLoc = R.getNameLoc(); 689 690 struct QueryState { 691 Sema &SemaRef; 692 DeclarationNameInfo NameInfo; 693 Sema::LookupNameKind LookupKind; 694 Sema::RedeclarationKind Redecl; 695 }; 696 QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(), 697 R.redeclarationKind()}; 698 RecordMemberExprValidatorCCC CCC(RTy); 699 TE = SemaRef.CorrectTypoDelayed( 700 R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC, 701 [=, &SemaRef](const TypoCorrection &TC) { 702 if (TC) { 703 assert(!TC.isKeyword() && 704 "Got a keyword as a correction for a member!"); 705 bool DroppedSpecifier = 706 TC.WillReplaceSpecifier() && 707 Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts()); 708 SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest) 709 << Typo << DC << DroppedSpecifier 710 << SS.getRange()); 711 } else { 712 SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange; 713 } 714 }, 715 [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable { 716 LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl); 717 R.clear(); // Ensure there's no decls lingering in the shared state. 718 R.suppressDiagnostics(); 719 R.setLookupName(TC.getCorrection()); 720 for (NamedDecl *ND : TC) 721 R.addDecl(ND); 722 R.resolveKind(); 723 return SemaRef.BuildMemberReferenceExpr( 724 BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(), 725 nullptr, R, nullptr, nullptr); 726 }, 727 Sema::CTK_ErrorRecovery, DC); 728 729 return false; 730 } 731 732 static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, 733 ExprResult &BaseExpr, bool &IsArrow, 734 SourceLocation OpLoc, CXXScopeSpec &SS, 735 Decl *ObjCImpDecl, bool HasTemplateArgs, 736 SourceLocation TemplateKWLoc); 737 738 ExprResult 739 Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, 740 SourceLocation OpLoc, bool IsArrow, 741 CXXScopeSpec &SS, 742 SourceLocation TemplateKWLoc, 743 NamedDecl *FirstQualifierInScope, 744 const DeclarationNameInfo &NameInfo, 745 const TemplateArgumentListInfo *TemplateArgs, 746 const Scope *S, 747 ActOnMemberAccessExtraArgs *ExtraArgs) { 748 if (BaseType->isDependentType() || 749 (SS.isSet() && isDependentScopeSpecifier(SS))) 750 return ActOnDependentMemberExpr(Base, BaseType, 751 IsArrow, OpLoc, 752 SS, TemplateKWLoc, FirstQualifierInScope, 753 NameInfo, TemplateArgs); 754 755 LookupResult R(*this, NameInfo, LookupMemberName); 756 757 // Implicit member accesses. 758 if (!Base) { 759 TypoExpr *TE = nullptr; 760 QualType RecordTy = BaseType; 761 if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType(); 762 if (LookupMemberExprInRecord( 763 *this, R, nullptr, RecordTy->getAs<RecordType>(), OpLoc, IsArrow, 764 SS, TemplateArgs != nullptr, TemplateKWLoc, TE)) 765 return ExprError(); 766 if (TE) 767 return TE; 768 769 // Explicit member accesses. 770 } else { 771 ExprResult BaseResult = Base; 772 ExprResult Result = 773 LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS, 774 ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr, 775 TemplateArgs != nullptr, TemplateKWLoc); 776 777 if (BaseResult.isInvalid()) 778 return ExprError(); 779 Base = BaseResult.get(); 780 781 if (Result.isInvalid()) 782 return ExprError(); 783 784 if (Result.get()) 785 return Result; 786 787 // LookupMemberExpr can modify Base, and thus change BaseType 788 BaseType = Base->getType(); 789 } 790 791 return BuildMemberReferenceExpr(Base, BaseType, 792 OpLoc, IsArrow, SS, TemplateKWLoc, 793 FirstQualifierInScope, R, TemplateArgs, S, 794 false, ExtraArgs); 795 } 796 797 ExprResult 798 Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, 799 SourceLocation loc, 800 IndirectFieldDecl *indirectField, 801 DeclAccessPair foundDecl, 802 Expr *baseObjectExpr, 803 SourceLocation opLoc) { 804 // First, build the expression that refers to the base object. 805 806 // Case 1: the base of the indirect field is not a field. 807 VarDecl *baseVariable = indirectField->getVarDecl(); 808 CXXScopeSpec EmptySS; 809 if (baseVariable) { 810 assert(baseVariable->getType()->isRecordType()); 811 812 // In principle we could have a member access expression that 813 // accesses an anonymous struct/union that's a static member of 814 // the base object's class. However, under the current standard, 815 // static data members cannot be anonymous structs or unions. 816 // Supporting this is as easy as building a MemberExpr here. 817 assert(!baseObjectExpr && "anonymous struct/union is static data member?"); 818 819 DeclarationNameInfo baseNameInfo(DeclarationName(), loc); 820 821 ExprResult result 822 = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable); 823 if (result.isInvalid()) return ExprError(); 824 825 baseObjectExpr = result.get(); 826 } 827 828 assert((baseVariable || baseObjectExpr) && 829 "referencing anonymous struct/union without a base variable or " 830 "expression"); 831 832 // Build the implicit member references to the field of the 833 // anonymous struct/union. 834 Expr *result = baseObjectExpr; 835 IndirectFieldDecl::chain_iterator 836 FI = indirectField->chain_begin(), FEnd = indirectField->chain_end(); 837 838 // Case 2: the base of the indirect field is a field and the user 839 // wrote a member expression. 840 if (!baseVariable) { 841 FieldDecl *field = cast<FieldDecl>(*FI); 842 843 bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType(); 844 845 // Make a nameInfo that properly uses the anonymous name. 846 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); 847 848 // Build the first member access in the chain with full information. 849 result = 850 BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(), 851 SS, field, foundDecl, memberNameInfo) 852 .get(); 853 if (!result) 854 return ExprError(); 855 } 856 857 // In all cases, we should now skip the first declaration in the chain. 858 ++FI; 859 860 while (FI != FEnd) { 861 FieldDecl *field = cast<FieldDecl>(*FI++); 862 863 // FIXME: these are somewhat meaningless 864 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); 865 DeclAccessPair fakeFoundDecl = 866 DeclAccessPair::make(field, field->getAccess()); 867 868 result = 869 BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(), 870 (FI == FEnd ? SS : EmptySS), field, 871 fakeFoundDecl, memberNameInfo) 872 .get(); 873 } 874 875 return result; 876 } 877 878 static ExprResult 879 BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, 880 const CXXScopeSpec &SS, 881 MSPropertyDecl *PD, 882 const DeclarationNameInfo &NameInfo) { 883 // Property names are always simple identifiers and therefore never 884 // require any interesting additional storage. 885 return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow, 886 S.Context.PseudoObjectTy, VK_LValue, 887 SS.getWithLocInContext(S.Context), 888 NameInfo.getLoc()); 889 } 890 891 MemberExpr *Sema::BuildMemberExpr( 892 Expr *Base, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec *SS, 893 SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, 894 bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, 895 QualType Ty, ExprValueKind VK, ExprObjectKind OK, 896 const TemplateArgumentListInfo *TemplateArgs) { 897 NestedNameSpecifierLoc NNS = 898 SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(); 899 return BuildMemberExpr(Base, IsArrow, OpLoc, NNS, TemplateKWLoc, Member, 900 FoundDecl, HadMultipleCandidates, MemberNameInfo, Ty, 901 VK, OK, TemplateArgs); 902 } 903 904 MemberExpr *Sema::BuildMemberExpr( 905 Expr *Base, bool IsArrow, SourceLocation OpLoc, NestedNameSpecifierLoc NNS, 906 SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl, 907 bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo, 908 QualType Ty, ExprValueKind VK, ExprObjectKind OK, 909 const TemplateArgumentListInfo *TemplateArgs) { 910 assert((!IsArrow || Base->isPRValue()) && 911 "-> base must be a pointer prvalue"); 912 MemberExpr *E = 913 MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc, 914 Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty, 915 VK, OK, getNonOdrUseReasonInCurrentContext(Member)); 916 E->setHadMultipleCandidates(HadMultipleCandidates); 917 MarkMemberReferenced(E); 918 919 // C++ [except.spec]p17: 920 // An exception-specification is considered to be needed when: 921 // - in an expression the function is the unique lookup result or the 922 // selected member of a set of overloaded functions 923 if (auto *FPT = Ty->getAs<FunctionProtoType>()) { 924 if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) { 925 if (auto *NewFPT = ResolveExceptionSpec(MemberNameInfo.getLoc(), FPT)) 926 E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers())); 927 } 928 } 929 930 return E; 931 } 932 933 /// Determine if the given scope is within a function-try-block handler. 934 static bool IsInFnTryBlockHandler(const Scope *S) { 935 // Walk the scope stack until finding a FnTryCatchScope, or leave the 936 // function scope. If a FnTryCatchScope is found, check whether the TryScope 937 // flag is set. If it is not, it's a function-try-block handler. 938 for (; S != S->getFnParent(); S = S->getParent()) { 939 if (S->getFlags() & Scope::FnTryCatchScope) 940 return (S->getFlags() & Scope::TryScope) != Scope::TryScope; 941 } 942 return false; 943 } 944 945 ExprResult 946 Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, 947 SourceLocation OpLoc, bool IsArrow, 948 const CXXScopeSpec &SS, 949 SourceLocation TemplateKWLoc, 950 NamedDecl *FirstQualifierInScope, 951 LookupResult &R, 952 const TemplateArgumentListInfo *TemplateArgs, 953 const Scope *S, 954 bool SuppressQualifierCheck, 955 ActOnMemberAccessExtraArgs *ExtraArgs) { 956 QualType BaseType = BaseExprType; 957 if (IsArrow) { 958 assert(BaseType->isPointerType()); 959 BaseType = BaseType->castAs<PointerType>()->getPointeeType(); 960 } 961 R.setBaseObjectType(BaseType); 962 963 // C++1z [expr.ref]p2: 964 // For the first option (dot) the first expression shall be a glvalue [...] 965 if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) { 966 ExprResult Converted = TemporaryMaterializationConversion(BaseExpr); 967 if (Converted.isInvalid()) 968 return ExprError(); 969 BaseExpr = Converted.get(); 970 } 971 972 const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo(); 973 DeclarationName MemberName = MemberNameInfo.getName(); 974 SourceLocation MemberLoc = MemberNameInfo.getLoc(); 975 976 if (R.isAmbiguous()) 977 return ExprError(); 978 979 // [except.handle]p10: Referring to any non-static member or base class of an 980 // object in the handler for a function-try-block of a constructor or 981 // destructor for that object results in undefined behavior. 982 const auto *FD = getCurFunctionDecl(); 983 if (S && BaseExpr && FD && 984 (isa<CXXDestructorDecl>(FD) || isa<CXXConstructorDecl>(FD)) && 985 isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts()) && 986 IsInFnTryBlockHandler(S)) 987 Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr) 988 << isa<CXXDestructorDecl>(FD); 989 990 if (R.empty()) { 991 // Rederive where we looked up. 992 DeclContext *DC = (SS.isSet() 993 ? computeDeclContext(SS, false) 994 : BaseType->castAs<RecordType>()->getDecl()); 995 996 if (ExtraArgs) { 997 ExprResult RetryExpr; 998 if (!IsArrow && BaseExpr) { 999 SFINAETrap Trap(*this, true); 1000 ParsedType ObjectType; 1001 bool MayBePseudoDestructor = false; 1002 RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr, 1003 OpLoc, tok::arrow, ObjectType, 1004 MayBePseudoDestructor); 1005 if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) { 1006 CXXScopeSpec TempSS(SS); 1007 RetryExpr = ActOnMemberAccessExpr( 1008 ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS, 1009 TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl); 1010 } 1011 if (Trap.hasErrorOccurred()) 1012 RetryExpr = ExprError(); 1013 } 1014 if (RetryExpr.isUsable()) { 1015 Diag(OpLoc, diag::err_no_member_overloaded_arrow) 1016 << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->"); 1017 return RetryExpr; 1018 } 1019 } 1020 1021 Diag(R.getNameLoc(), diag::err_no_member) 1022 << MemberName << DC 1023 << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange()); 1024 return ExprError(); 1025 } 1026 1027 // Diagnose lookups that find only declarations from a non-base 1028 // type. This is possible for either qualified lookups (which may 1029 // have been qualified with an unrelated type) or implicit member 1030 // expressions (which were found with unqualified lookup and thus 1031 // may have come from an enclosing scope). Note that it's okay for 1032 // lookup to find declarations from a non-base type as long as those 1033 // aren't the ones picked by overload resolution. 1034 if ((SS.isSet() || !BaseExpr || 1035 (isa<CXXThisExpr>(BaseExpr) && 1036 cast<CXXThisExpr>(BaseExpr)->isImplicit())) && 1037 !SuppressQualifierCheck && 1038 CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R)) 1039 return ExprError(); 1040 1041 // Construct an unresolved result if we in fact got an unresolved 1042 // result. 1043 if (R.isOverloadedResult() || R.isUnresolvableResult()) { 1044 // Suppress any lookup-related diagnostics; we'll do these when we 1045 // pick a member. 1046 R.suppressDiagnostics(); 1047 1048 UnresolvedMemberExpr *MemExpr 1049 = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(), 1050 BaseExpr, BaseExprType, 1051 IsArrow, OpLoc, 1052 SS.getWithLocInContext(Context), 1053 TemplateKWLoc, MemberNameInfo, 1054 TemplateArgs, R.begin(), R.end()); 1055 1056 return MemExpr; 1057 } 1058 1059 assert(R.isSingleResult()); 1060 DeclAccessPair FoundDecl = R.begin().getPair(); 1061 NamedDecl *MemberDecl = R.getFoundDecl(); 1062 1063 // FIXME: diagnose the presence of template arguments now. 1064 1065 // If the decl being referenced had an error, return an error for this 1066 // sub-expr without emitting another error, in order to avoid cascading 1067 // error cases. 1068 if (MemberDecl->isInvalidDecl()) 1069 return ExprError(); 1070 1071 // Handle the implicit-member-access case. 1072 if (!BaseExpr) { 1073 // If this is not an instance member, convert to a non-member access. 1074 if (!MemberDecl->isCXXInstanceMember()) { 1075 // We might have a variable template specialization (or maybe one day a 1076 // member concept-id). 1077 if (TemplateArgs || TemplateKWLoc.isValid()) 1078 return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/false, TemplateArgs); 1079 1080 return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl, 1081 FoundDecl, TemplateArgs); 1082 } 1083 SourceLocation Loc = R.getNameLoc(); 1084 if (SS.getRange().isValid()) 1085 Loc = SS.getRange().getBegin(); 1086 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true); 1087 } 1088 1089 // Check the use of this member. 1090 if (DiagnoseUseOfDecl(MemberDecl, MemberLoc)) 1091 return ExprError(); 1092 1093 if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) 1094 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl, 1095 MemberNameInfo); 1096 1097 if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl)) 1098 return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD, 1099 MemberNameInfo); 1100 1101 if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl)) 1102 // We may have found a field within an anonymous union or struct 1103 // (C++ [class.union]). 1104 return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD, 1105 FoundDecl, BaseExpr, 1106 OpLoc); 1107 1108 if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) { 1109 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var, 1110 FoundDecl, /*HadMultipleCandidates=*/false, 1111 MemberNameInfo, Var->getType().getNonReferenceType(), 1112 VK_LValue, OK_Ordinary); 1113 } 1114 1115 if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) { 1116 ExprValueKind valueKind; 1117 QualType type; 1118 if (MemberFn->isInstance()) { 1119 valueKind = VK_PRValue; 1120 type = Context.BoundMemberTy; 1121 } else { 1122 valueKind = VK_LValue; 1123 type = MemberFn->getType(); 1124 } 1125 1126 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, 1127 MemberFn, FoundDecl, /*HadMultipleCandidates=*/false, 1128 MemberNameInfo, type, valueKind, OK_Ordinary); 1129 } 1130 assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?"); 1131 1132 if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) { 1133 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Enum, 1134 FoundDecl, /*HadMultipleCandidates=*/false, 1135 MemberNameInfo, Enum->getType(), VK_PRValue, 1136 OK_Ordinary); 1137 } 1138 1139 if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) { 1140 if (!TemplateArgs) { 1141 diagnoseMissingTemplateArguments(TemplateName(VarTempl), MemberLoc); 1142 return ExprError(); 1143 } 1144 1145 DeclResult VDecl = CheckVarTemplateId(VarTempl, TemplateKWLoc, 1146 MemberNameInfo.getLoc(), *TemplateArgs); 1147 if (VDecl.isInvalid()) 1148 return ExprError(); 1149 1150 // Non-dependent member, but dependent template arguments. 1151 if (!VDecl.get()) 1152 return ActOnDependentMemberExpr( 1153 BaseExpr, BaseExpr->getType(), IsArrow, OpLoc, SS, TemplateKWLoc, 1154 FirstQualifierInScope, MemberNameInfo, TemplateArgs); 1155 1156 VarDecl *Var = cast<VarDecl>(VDecl.get()); 1157 if (!Var->getTemplateSpecializationKind()) 1158 Var->setTemplateSpecializationKind(TSK_ImplicitInstantiation, MemberLoc); 1159 1160 return BuildMemberExpr( 1161 BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var, FoundDecl, 1162 /*HadMultipleCandidates=*/false, MemberNameInfo, 1163 Var->getType().getNonReferenceType(), VK_LValue, OK_Ordinary); 1164 } 1165 1166 // We found something that we didn't expect. Complain. 1167 if (isa<TypeDecl>(MemberDecl)) 1168 Diag(MemberLoc, diag::err_typecheck_member_reference_type) 1169 << MemberName << BaseType << int(IsArrow); 1170 else 1171 Diag(MemberLoc, diag::err_typecheck_member_reference_unknown) 1172 << MemberName << BaseType << int(IsArrow); 1173 1174 Diag(MemberDecl->getLocation(), diag::note_member_declared_here) 1175 << MemberName; 1176 R.suppressDiagnostics(); 1177 return ExprError(); 1178 } 1179 1180 /// Given that normal member access failed on the given expression, 1181 /// and given that the expression's type involves builtin-id or 1182 /// builtin-Class, decide whether substituting in the redefinition 1183 /// types would be profitable. The redefinition type is whatever 1184 /// this translation unit tried to typedef to id/Class; we store 1185 /// it to the side and then re-use it in places like this. 1186 static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base) { 1187 const ObjCObjectPointerType *opty 1188 = base.get()->getType()->getAs<ObjCObjectPointerType>(); 1189 if (!opty) return false; 1190 1191 const ObjCObjectType *ty = opty->getObjectType(); 1192 1193 QualType redef; 1194 if (ty->isObjCId()) { 1195 redef = S.Context.getObjCIdRedefinitionType(); 1196 } else if (ty->isObjCClass()) { 1197 redef = S.Context.getObjCClassRedefinitionType(); 1198 } else { 1199 return false; 1200 } 1201 1202 // Do the substitution as long as the redefinition type isn't just a 1203 // possibly-qualified pointer to builtin-id or builtin-Class again. 1204 opty = redef->getAs<ObjCObjectPointerType>(); 1205 if (opty && !opty->getObjectType()->getInterface()) 1206 return false; 1207 1208 base = S.ImpCastExprToType(base.get(), redef, CK_BitCast); 1209 return true; 1210 } 1211 1212 static bool isRecordType(QualType T) { 1213 return T->isRecordType(); 1214 } 1215 static bool isPointerToRecordType(QualType T) { 1216 if (const PointerType *PT = T->getAs<PointerType>()) 1217 return PT->getPointeeType()->isRecordType(); 1218 return false; 1219 } 1220 1221 /// Perform conversions on the LHS of a member access expression. 1222 ExprResult 1223 Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) { 1224 if (IsArrow && !Base->getType()->isFunctionType()) 1225 return DefaultFunctionArrayLvalueConversion(Base); 1226 1227 return CheckPlaceholderExpr(Base); 1228 } 1229 1230 /// Look up the given member of the given non-type-dependent 1231 /// expression. This can return in one of two ways: 1232 /// * If it returns a sentinel null-but-valid result, the caller will 1233 /// assume that lookup was performed and the results written into 1234 /// the provided structure. It will take over from there. 1235 /// * Otherwise, the returned expression will be produced in place of 1236 /// an ordinary member expression. 1237 /// 1238 /// The ObjCImpDecl bit is a gross hack that will need to be properly 1239 /// fixed for ObjC++. 1240 static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, 1241 ExprResult &BaseExpr, bool &IsArrow, 1242 SourceLocation OpLoc, CXXScopeSpec &SS, 1243 Decl *ObjCImpDecl, bool HasTemplateArgs, 1244 SourceLocation TemplateKWLoc) { 1245 assert(BaseExpr.get() && "no base expression"); 1246 1247 // Perform default conversions. 1248 BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow); 1249 if (BaseExpr.isInvalid()) 1250 return ExprError(); 1251 1252 QualType BaseType = BaseExpr.get()->getType(); 1253 assert(!BaseType->isDependentType()); 1254 1255 DeclarationName MemberName = R.getLookupName(); 1256 SourceLocation MemberLoc = R.getNameLoc(); 1257 1258 // For later type-checking purposes, turn arrow accesses into dot 1259 // accesses. The only access type we support that doesn't follow 1260 // the C equivalence "a->b === (*a).b" is ObjC property accesses, 1261 // and those never use arrows, so this is unaffected. 1262 if (IsArrow) { 1263 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) 1264 BaseType = Ptr->getPointeeType(); 1265 else if (const ObjCObjectPointerType *Ptr 1266 = BaseType->getAs<ObjCObjectPointerType>()) 1267 BaseType = Ptr->getPointeeType(); 1268 else if (BaseType->isRecordType()) { 1269 // Recover from arrow accesses to records, e.g.: 1270 // struct MyRecord foo; 1271 // foo->bar 1272 // This is actually well-formed in C++ if MyRecord has an 1273 // overloaded operator->, but that should have been dealt with 1274 // by now--or a diagnostic message already issued if a problem 1275 // was encountered while looking for the overloaded operator->. 1276 if (!S.getLangOpts().CPlusPlus) { 1277 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) 1278 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() 1279 << FixItHint::CreateReplacement(OpLoc, "."); 1280 } 1281 IsArrow = false; 1282 } else if (BaseType->isFunctionType()) { 1283 goto fail; 1284 } else { 1285 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) 1286 << BaseType << BaseExpr.get()->getSourceRange(); 1287 return ExprError(); 1288 } 1289 } 1290 1291 // Handle field access to simple records. 1292 if (const RecordType *RTy = BaseType->getAs<RecordType>()) { 1293 TypoExpr *TE = nullptr; 1294 if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, OpLoc, IsArrow, SS, 1295 HasTemplateArgs, TemplateKWLoc, TE)) 1296 return ExprError(); 1297 1298 // Returning valid-but-null is how we indicate to the caller that 1299 // the lookup result was filled in. If typo correction was attempted and 1300 // failed, the lookup result will have been cleared--that combined with the 1301 // valid-but-null ExprResult will trigger the appropriate diagnostics. 1302 return ExprResult(TE); 1303 } 1304 1305 // Handle ivar access to Objective-C objects. 1306 if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) { 1307 if (!SS.isEmpty() && !SS.isInvalid()) { 1308 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access) 1309 << 1 << SS.getScopeRep() 1310 << FixItHint::CreateRemoval(SS.getRange()); 1311 SS.clear(); 1312 } 1313 1314 IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); 1315 1316 // There are three cases for the base type: 1317 // - builtin id (qualified or unqualified) 1318 // - builtin Class (qualified or unqualified) 1319 // - an interface 1320 ObjCInterfaceDecl *IDecl = OTy->getInterface(); 1321 if (!IDecl) { 1322 if (S.getLangOpts().ObjCAutoRefCount && 1323 (OTy->isObjCId() || OTy->isObjCClass())) 1324 goto fail; 1325 // There's an implicit 'isa' ivar on all objects. 1326 // But we only actually find it this way on objects of type 'id', 1327 // apparently. 1328 if (OTy->isObjCId() && Member->isStr("isa")) 1329 return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc, 1330 OpLoc, S.Context.getObjCClassType()); 1331 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) 1332 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1333 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1334 goto fail; 1335 } 1336 1337 if (S.RequireCompleteType(OpLoc, BaseType, 1338 diag::err_typecheck_incomplete_tag, 1339 BaseExpr.get())) 1340 return ExprError(); 1341 1342 ObjCInterfaceDecl *ClassDeclared = nullptr; 1343 ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared); 1344 1345 if (!IV) { 1346 // Attempt to correct for typos in ivar names. 1347 DeclFilterCCC<ObjCIvarDecl> Validator{}; 1348 Validator.IsObjCIvarLookup = IsArrow; 1349 if (TypoCorrection Corrected = S.CorrectTypo( 1350 R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr, 1351 Validator, Sema::CTK_ErrorRecovery, IDecl)) { 1352 IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>(); 1353 S.diagnoseTypo( 1354 Corrected, 1355 S.PDiag(diag::err_typecheck_member_reference_ivar_suggest) 1356 << IDecl->getDeclName() << MemberName); 1357 1358 // Figure out the class that declares the ivar. 1359 assert(!ClassDeclared); 1360 1361 Decl *D = cast<Decl>(IV->getDeclContext()); 1362 if (auto *Category = dyn_cast<ObjCCategoryDecl>(D)) 1363 D = Category->getClassInterface(); 1364 1365 if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D)) 1366 ClassDeclared = Implementation->getClassInterface(); 1367 else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D)) 1368 ClassDeclared = Interface; 1369 1370 assert(ClassDeclared && "cannot query interface"); 1371 } else { 1372 if (IsArrow && 1373 IDecl->FindPropertyDeclaration( 1374 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { 1375 S.Diag(MemberLoc, diag::err_property_found_suggest) 1376 << Member << BaseExpr.get()->getType() 1377 << FixItHint::CreateReplacement(OpLoc, "."); 1378 return ExprError(); 1379 } 1380 1381 S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar) 1382 << IDecl->getDeclName() << MemberName 1383 << BaseExpr.get()->getSourceRange(); 1384 return ExprError(); 1385 } 1386 } 1387 1388 assert(ClassDeclared); 1389 1390 // If the decl being referenced had an error, return an error for this 1391 // sub-expr without emitting another error, in order to avoid cascading 1392 // error cases. 1393 if (IV->isInvalidDecl()) 1394 return ExprError(); 1395 1396 // Check whether we can reference this field. 1397 if (S.DiagnoseUseOfDecl(IV, MemberLoc)) 1398 return ExprError(); 1399 if (IV->getAccessControl() != ObjCIvarDecl::Public && 1400 IV->getAccessControl() != ObjCIvarDecl::Package) { 1401 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr; 1402 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) 1403 ClassOfMethodDecl = MD->getClassInterface(); 1404 else if (ObjCImpDecl && S.getCurFunctionDecl()) { 1405 // Case of a c-function declared inside an objc implementation. 1406 // FIXME: For a c-style function nested inside an objc implementation 1407 // class, there is no implementation context available, so we pass 1408 // down the context as argument to this routine. Ideally, this context 1409 // need be passed down in the AST node and somehow calculated from the 1410 // AST for a function decl. 1411 if (ObjCImplementationDecl *IMPD = 1412 dyn_cast<ObjCImplementationDecl>(ObjCImpDecl)) 1413 ClassOfMethodDecl = IMPD->getClassInterface(); 1414 else if (ObjCCategoryImplDecl* CatImplClass = 1415 dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl)) 1416 ClassOfMethodDecl = CatImplClass->getClassInterface(); 1417 } 1418 if (!S.getLangOpts().DebuggerSupport) { 1419 if (IV->getAccessControl() == ObjCIvarDecl::Private) { 1420 if (!declaresSameEntity(ClassDeclared, IDecl) || 1421 !declaresSameEntity(ClassOfMethodDecl, ClassDeclared)) 1422 S.Diag(MemberLoc, diag::err_private_ivar_access) 1423 << IV->getDeclName(); 1424 } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl)) 1425 // @protected 1426 S.Diag(MemberLoc, diag::err_protected_ivar_access) 1427 << IV->getDeclName(); 1428 } 1429 } 1430 bool warn = true; 1431 if (S.getLangOpts().ObjCWeak) { 1432 Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts(); 1433 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp)) 1434 if (UO->getOpcode() == UO_Deref) 1435 BaseExp = UO->getSubExpr()->IgnoreParenCasts(); 1436 1437 if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp)) 1438 if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { 1439 S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access); 1440 warn = false; 1441 } 1442 } 1443 if (warn) { 1444 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) { 1445 ObjCMethodFamily MF = MD->getMethodFamily(); 1446 warn = (MF != OMF_init && MF != OMF_dealloc && 1447 MF != OMF_finalize && 1448 !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV)); 1449 } 1450 if (warn) 1451 S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName(); 1452 } 1453 1454 ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr( 1455 IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(), 1456 IsArrow); 1457 1458 if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { 1459 if (!S.isUnevaluatedContext() && 1460 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc)) 1461 S.getCurFunction()->recordUseOfWeak(Result); 1462 } 1463 1464 return Result; 1465 } 1466 1467 // Objective-C property access. 1468 const ObjCObjectPointerType *OPT; 1469 if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) { 1470 if (!SS.isEmpty() && !SS.isInvalid()) { 1471 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access) 1472 << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange()); 1473 SS.clear(); 1474 } 1475 1476 // This actually uses the base as an r-value. 1477 BaseExpr = S.DefaultLvalueConversion(BaseExpr.get()); 1478 if (BaseExpr.isInvalid()) 1479 return ExprError(); 1480 1481 assert(S.Context.hasSameUnqualifiedType(BaseType, 1482 BaseExpr.get()->getType())); 1483 1484 IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); 1485 1486 const ObjCObjectType *OT = OPT->getObjectType(); 1487 1488 // id, with and without qualifiers. 1489 if (OT->isObjCId()) { 1490 // Check protocols on qualified interfaces. 1491 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member); 1492 if (Decl *PMDecl = 1493 FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) { 1494 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) { 1495 // Check the use of this declaration 1496 if (S.DiagnoseUseOfDecl(PD, MemberLoc)) 1497 return ExprError(); 1498 1499 return new (S.Context) 1500 ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue, 1501 OK_ObjCProperty, MemberLoc, BaseExpr.get()); 1502 } 1503 1504 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) { 1505 Selector SetterSel = 1506 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), 1507 S.PP.getSelectorTable(), 1508 Member); 1509 ObjCMethodDecl *SMD = nullptr; 1510 if (Decl *SDecl = FindGetterSetterNameDecl(OPT, 1511 /*Property id*/ nullptr, 1512 SetterSel, S.Context)) 1513 SMD = dyn_cast<ObjCMethodDecl>(SDecl); 1514 1515 return new (S.Context) 1516 ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue, 1517 OK_ObjCProperty, MemberLoc, BaseExpr.get()); 1518 } 1519 } 1520 // Use of id.member can only be for a property reference. Do not 1521 // use the 'id' redefinition in this case. 1522 if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr)) 1523 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1524 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1525 1526 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) 1527 << MemberName << BaseType); 1528 } 1529 1530 // 'Class', unqualified only. 1531 if (OT->isObjCClass()) { 1532 // Only works in a method declaration (??!). 1533 ObjCMethodDecl *MD = S.getCurMethodDecl(); 1534 if (!MD) { 1535 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) 1536 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1537 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1538 1539 goto fail; 1540 } 1541 1542 // Also must look for a getter name which uses property syntax. 1543 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member); 1544 ObjCInterfaceDecl *IFace = MD->getClassInterface(); 1545 if (!IFace) 1546 goto fail; 1547 1548 ObjCMethodDecl *Getter; 1549 if ((Getter = IFace->lookupClassMethod(Sel))) { 1550 // Check the use of this method. 1551 if (S.DiagnoseUseOfDecl(Getter, MemberLoc)) 1552 return ExprError(); 1553 } else 1554 Getter = IFace->lookupPrivateMethod(Sel, false); 1555 // If we found a getter then this may be a valid dot-reference, we 1556 // will look for the matching setter, in case it is needed. 1557 Selector SetterSel = 1558 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(), 1559 S.PP.getSelectorTable(), 1560 Member); 1561 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel); 1562 if (!Setter) { 1563 // If this reference is in an @implementation, also check for 'private' 1564 // methods. 1565 Setter = IFace->lookupPrivateMethod(SetterSel, false); 1566 } 1567 1568 if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc)) 1569 return ExprError(); 1570 1571 if (Getter || Setter) { 1572 return new (S.Context) ObjCPropertyRefExpr( 1573 Getter, Setter, S.Context.PseudoObjectTy, VK_LValue, 1574 OK_ObjCProperty, MemberLoc, BaseExpr.get()); 1575 } 1576 1577 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr)) 1578 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1579 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1580 1581 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found) 1582 << MemberName << BaseType); 1583 } 1584 1585 // Normal property access. 1586 return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName, 1587 MemberLoc, SourceLocation(), QualType(), 1588 false); 1589 } 1590 1591 // Handle 'field access' to vectors, such as 'V.xx'. 1592 if (BaseType->isExtVectorType()) { 1593 // FIXME: this expr should store IsArrow. 1594 IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); 1595 ExprValueKind VK; 1596 if (IsArrow) 1597 VK = VK_LValue; 1598 else { 1599 if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(BaseExpr.get())) 1600 VK = POE->getSyntacticForm()->getValueKind(); 1601 else 1602 VK = BaseExpr.get()->getValueKind(); 1603 } 1604 1605 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc, 1606 Member, MemberLoc); 1607 if (ret.isNull()) 1608 return ExprError(); 1609 Qualifiers BaseQ = 1610 S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers(); 1611 ret = S.Context.getQualifiedType(ret, BaseQ); 1612 1613 return new (S.Context) 1614 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc); 1615 } 1616 1617 // Adjust builtin-sel to the appropriate redefinition type if that's 1618 // not just a pointer to builtin-sel again. 1619 if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) && 1620 !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) { 1621 BaseExpr = S.ImpCastExprToType( 1622 BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast); 1623 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1624 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1625 } 1626 1627 // Failure cases. 1628 fail: 1629 1630 // Recover from dot accesses to pointers, e.g.: 1631 // type *foo; 1632 // foo.bar 1633 // This is actually well-formed in two cases: 1634 // - 'type' is an Objective C type 1635 // - 'bar' is a pseudo-destructor name which happens to refer to 1636 // the appropriate pointer type 1637 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) { 1638 if (!IsArrow && Ptr->getPointeeType()->isRecordType() && 1639 MemberName.getNameKind() != DeclarationName::CXXDestructorName) { 1640 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) 1641 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() 1642 << FixItHint::CreateReplacement(OpLoc, "->"); 1643 1644 // Recurse as an -> access. 1645 IsArrow = true; 1646 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1647 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1648 } 1649 } 1650 1651 // If the user is trying to apply -> or . to a function name, it's probably 1652 // because they forgot parentheses to call that function. 1653 if (S.tryToRecoverWithCall( 1654 BaseExpr, S.PDiag(diag::err_member_reference_needs_call), 1655 /*complain*/ false, 1656 IsArrow ? &isPointerToRecordType : &isRecordType)) { 1657 if (BaseExpr.isInvalid()) 1658 return ExprError(); 1659 BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get()); 1660 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, 1661 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc); 1662 } 1663 1664 S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union) 1665 << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc; 1666 1667 return ExprError(); 1668 } 1669 1670 /// The main callback when the parser finds something like 1671 /// expression . [nested-name-specifier] identifier 1672 /// expression -> [nested-name-specifier] identifier 1673 /// where 'identifier' encompasses a fairly broad spectrum of 1674 /// possibilities, including destructor and operator references. 1675 /// 1676 /// \param OpKind either tok::arrow or tok::period 1677 /// \param ObjCImpDecl the current Objective-C \@implementation 1678 /// decl; this is an ugly hack around the fact that Objective-C 1679 /// \@implementations aren't properly put in the context chain 1680 ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base, 1681 SourceLocation OpLoc, 1682 tok::TokenKind OpKind, 1683 CXXScopeSpec &SS, 1684 SourceLocation TemplateKWLoc, 1685 UnqualifiedId &Id, 1686 Decl *ObjCImpDecl) { 1687 if (SS.isSet() && SS.isInvalid()) 1688 return ExprError(); 1689 1690 // Warn about the explicit constructor calls Microsoft extension. 1691 if (getLangOpts().MicrosoftExt && 1692 Id.getKind() == UnqualifiedIdKind::IK_ConstructorName) 1693 Diag(Id.getSourceRange().getBegin(), 1694 diag::ext_ms_explicit_constructor_call); 1695 1696 TemplateArgumentListInfo TemplateArgsBuffer; 1697 1698 // Decompose the name into its component parts. 1699 DeclarationNameInfo NameInfo; 1700 const TemplateArgumentListInfo *TemplateArgs; 1701 DecomposeUnqualifiedId(Id, TemplateArgsBuffer, 1702 NameInfo, TemplateArgs); 1703 1704 DeclarationName Name = NameInfo.getName(); 1705 bool IsArrow = (OpKind == tok::arrow); 1706 1707 NamedDecl *FirstQualifierInScope 1708 = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep())); 1709 1710 // This is a postfix expression, so get rid of ParenListExprs. 1711 ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); 1712 if (Result.isInvalid()) return ExprError(); 1713 Base = Result.get(); 1714 1715 if (Base->getType()->isDependentType() || Name.isDependentName() || 1716 isDependentScopeSpecifier(SS)) { 1717 return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS, 1718 TemplateKWLoc, FirstQualifierInScope, 1719 NameInfo, TemplateArgs); 1720 } 1721 1722 ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl}; 1723 ExprResult Res = BuildMemberReferenceExpr( 1724 Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc, 1725 FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs); 1726 1727 if (!Res.isInvalid() && isa<MemberExpr>(Res.get())) 1728 CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get())); 1729 1730 return Res; 1731 } 1732 1733 void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) { 1734 if (isUnevaluatedContext()) 1735 return; 1736 1737 QualType ResultTy = E->getType(); 1738 1739 // Member accesses have four cases: 1740 // 1: non-array member via "->": dereferences 1741 // 2: non-array member via ".": nothing interesting happens 1742 // 3: array member access via "->": nothing interesting happens 1743 // (this returns an array lvalue and does not actually dereference memory) 1744 // 4: array member access via ".": *adds* a layer of indirection 1745 if (ResultTy->isArrayType()) { 1746 if (!E->isArrow()) { 1747 // This might be something like: 1748 // (*structPtr).arrayMember 1749 // which behaves roughly like: 1750 // &(*structPtr).pointerMember 1751 // in that the apparent dereference in the base expression does not 1752 // actually happen. 1753 CheckAddressOfNoDeref(E->getBase()); 1754 } 1755 } else if (E->isArrow()) { 1756 if (const auto *Ptr = dyn_cast<PointerType>( 1757 E->getBase()->getType().getDesugaredType(Context))) { 1758 if (Ptr->getPointeeType()->hasAttr(attr::NoDeref)) 1759 ExprEvalContexts.back().PossibleDerefs.insert(E); 1760 } 1761 } 1762 } 1763 1764 ExprResult 1765 Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, 1766 SourceLocation OpLoc, const CXXScopeSpec &SS, 1767 FieldDecl *Field, DeclAccessPair FoundDecl, 1768 const DeclarationNameInfo &MemberNameInfo) { 1769 // x.a is an l-value if 'a' has a reference type. Otherwise: 1770 // x.a is an l-value/x-value/pr-value if the base is (and note 1771 // that *x is always an l-value), except that if the base isn't 1772 // an ordinary object then we must have an rvalue. 1773 ExprValueKind VK = VK_LValue; 1774 ExprObjectKind OK = OK_Ordinary; 1775 if (!IsArrow) { 1776 if (BaseExpr->getObjectKind() == OK_Ordinary) 1777 VK = BaseExpr->getValueKind(); 1778 else 1779 VK = VK_PRValue; 1780 } 1781 if (VK != VK_PRValue && Field->isBitField()) 1782 OK = OK_BitField; 1783 1784 // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] 1785 QualType MemberType = Field->getType(); 1786 if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) { 1787 MemberType = Ref->getPointeeType(); 1788 VK = VK_LValue; 1789 } else { 1790 QualType BaseType = BaseExpr->getType(); 1791 if (IsArrow) BaseType = BaseType->castAs<PointerType>()->getPointeeType(); 1792 1793 Qualifiers BaseQuals = BaseType.getQualifiers(); 1794 1795 // GC attributes are never picked up by members. 1796 BaseQuals.removeObjCGCAttr(); 1797 1798 // CVR attributes from the base are picked up by members, 1799 // except that 'mutable' members don't pick up 'const'. 1800 if (Field->isMutable()) BaseQuals.removeConst(); 1801 1802 Qualifiers MemberQuals = 1803 Context.getCanonicalType(MemberType).getQualifiers(); 1804 1805 assert(!MemberQuals.hasAddressSpace()); 1806 1807 Qualifiers Combined = BaseQuals + MemberQuals; 1808 if (Combined != MemberQuals) 1809 MemberType = Context.getQualifiedType(MemberType, Combined); 1810 1811 // Pick up NoDeref from the base in case we end up using AddrOf on the 1812 // result. E.g. the expression 1813 // &someNoDerefPtr->pointerMember 1814 // should be a noderef pointer again. 1815 if (BaseType->hasAttr(attr::NoDeref)) 1816 MemberType = 1817 Context.getAttributedType(attr::NoDeref, MemberType, MemberType); 1818 } 1819 1820 auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext); 1821 if (!(CurMethod && CurMethod->isDefaulted())) 1822 UnusedPrivateFields.remove(Field); 1823 1824 ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(), 1825 FoundDecl, Field); 1826 if (Base.isInvalid()) 1827 return ExprError(); 1828 1829 // Build a reference to a private copy for non-static data members in 1830 // non-static member functions, privatized by OpenMP constructs. 1831 if (getLangOpts().OpenMP && IsArrow && 1832 !CurContext->isDependentContext() && 1833 isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) { 1834 if (auto *PrivateCopy = isOpenMPCapturedDecl(Field)) { 1835 return getOpenMPCapturedExpr(PrivateCopy, VK, OK, 1836 MemberNameInfo.getLoc()); 1837 } 1838 } 1839 1840 return BuildMemberExpr(Base.get(), IsArrow, OpLoc, &SS, 1841 /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, 1842 /*HadMultipleCandidates=*/false, MemberNameInfo, 1843 MemberType, VK, OK); 1844 } 1845 1846 /// Builds an implicit member access expression. The current context 1847 /// is known to be an instance method, and the given unqualified lookup 1848 /// set is known to contain only instance members, at least one of which 1849 /// is from an appropriate type. 1850 ExprResult 1851 Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, 1852 SourceLocation TemplateKWLoc, 1853 LookupResult &R, 1854 const TemplateArgumentListInfo *TemplateArgs, 1855 bool IsKnownInstance, const Scope *S) { 1856 assert(!R.empty() && !R.isAmbiguous()); 1857 1858 SourceLocation loc = R.getNameLoc(); 1859 1860 // If this is known to be an instance access, go ahead and build an 1861 // implicit 'this' expression now. 1862 QualType ThisTy = getCurrentThisType(); 1863 assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'"); 1864 1865 Expr *baseExpr = nullptr; // null signifies implicit access 1866 if (IsKnownInstance) { 1867 SourceLocation Loc = R.getNameLoc(); 1868 if (SS.getRange().isValid()) 1869 Loc = SS.getRange().getBegin(); 1870 baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true); 1871 } 1872 1873 return BuildMemberReferenceExpr(baseExpr, ThisTy, 1874 /*OpLoc*/ SourceLocation(), 1875 /*IsArrow*/ true, 1876 SS, TemplateKWLoc, 1877 /*FirstQualifierInScope*/ nullptr, 1878 R, TemplateArgs, S); 1879 } 1880