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