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