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