clang  19.0.0git
SemaExprMember.cpp
Go to the documentation of this file.
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"
24 #include "clang/Sema/SemaObjC.h"
25 #include "clang/Sema/SemaOpenMP.h"
26 
27 using namespace clang;
28 using namespace sema;
29 
31 
32 /// Determines if the given class is provably not derived from all of
33 /// the prospective base classes.
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.
45 
46  /// The reference may be an implicit instance member access.
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.
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.
56 
57  /// The reference is definitely an implicit instance member access.
59 
60  /// The reference may be to an unresolved using declaration.
62 
63  /// The reference is a contextually-permitted abstract member reference.
65 
66  /// Whether the context is static is dependent on the enclosing template (i.e.
67  /// in a dependent class scope explicit specialization).
69 
70  /// The reference may be to an unresolved using declaration and the
71  /// context is not an instance method.
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.
78 
79  /// All possible referrents are instance members and the current
80  /// context is not an instance method.
82 
83  /// All possible referrents are instance members of an unrelated
84  /// class.
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.
95  const LookupResult &R) {
96  assert(!R.empty() && (*R.begin())->isCXXClassMember());
97 
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) {
160  if (isField && SemaRef.getLangOpts().CPlusPlus11)
161  AbstractInstanceResult = IMA_Field_Uneval_Context;
162  break;
163 
165  AbstractInstanceResult = IMA_Abstract;
166  break;
167 
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)
181 
182  return AbstractInstanceResult ? AbstractInstanceResult
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
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() !=
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 :
218 
219  return (hasNonInstance ? IMA_Mixed : IMA_Instance);
220 }
221 
222 /// Diagnose a reference to a field with no object available.
223 static void diagnoseInstanceReference(Sema &SemaRef,
224  const CXXScopeSpec &SS,
225  NamedDecl *Rep,
226  const DeclarationNameInfo &nameInfo) {
227  SourceLocation Loc = nameInfo.getLoc();
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 
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 
305 /// Builds an expression which might be an implicit member expression.
307  const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R,
308  const TemplateArgumentListInfo *TemplateArgs, const Scope *S) {
309  switch (IMAKind Classification = ClassifyImplicitMemberAccess(*this, R)) {
310  case IMA_Instance:
311  case IMA_Mixed:
312  case IMA_Mixed_Unrelated:
313  case IMA_Unresolved:
314  return BuildImplicitMemberExpr(
315  SS, TemplateKWLoc, R, TemplateArgs,
316  /*IsKnownInstance=*/Classification == IMA_Instance, S);
318  Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
319  << R.getLookupNameInfo().getName();
320  [[fallthrough]];
321  case IMA_Static:
322  case IMA_Abstract:
325  if (TemplateArgs || TemplateKWLoc.isValid())
326  return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*RequiresADL=*/false,
327  TemplateArgs);
328  return BuildDeclarationNameExpr(SS, R, /*NeedsADL=*/false,
329  /*AcceptInvalidDecl=*/false);
330  case IMA_Dependent:
333  Context, R.getNamingClass(), SS.getWithLocInContext(Context),
334  TemplateKWLoc, R.getLookupNameInfo(), /*RequiresADL=*/false,
335  TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true);
336 
338  case IMA_Error_Unrelated:
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
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.
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
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 &&
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
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 
507  IdentifierInfo *Member,
508  const Selector &Sel,
509  ASTContext &Context) {
510  if (Member)
511  if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(
513  return PD;
514  if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
515  return OMD;
516 
517  for (const auto *I : PDecl->protocols()) {
519  Context))
520  return D;
521  }
522  return nullptr;
523 }
524 
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(
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 
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.
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.
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 
616 // Check whether the declarations we found through a nested-name
617 // specifier in a member expression are actually members of the base
618 // type. The restriction here is:
619 //
620 // C++ [expr.ref]p2:
621 // ... In these cases, the id-expression shall name a
622 // member of the class or of one of its base classes.
623 //
624 // So it's perfectly legitimate for the nested-name specifier to name
625 // an unrelated class, and for us to find an overload set including
626 // decls from classes which are not superclasses, as long as the decl
627 // we actually pick through overload resolution is from a superclass.
629  QualType BaseType,
630  const CXXScopeSpec &SS,
631  const LookupResult &R) {
632  CXXRecordDecl *BaseRecord =
633  cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType));
634  if (!BaseRecord) {
635  // We can't check this yet because the base type is still
636  // dependent.
637  assert(BaseType->isDependentType());
638  return false;
639  }
640 
641  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
642  // If this is an implicit member reference and we find a
643  // non-instance member, it's not an error.
644  if (!BaseExpr && !(*I)->isCXXInstanceMember())
645  return false;
646 
647  // Note that we use the DC of the decl, not the underlying decl.
648  DeclContext *DC = (*I)->getDeclContext()->getNonTransparentContext();
649  if (!DC->isRecord())
650  continue;
651 
652  CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
653  if (BaseRecord->getCanonicalDecl() == MemberRecord ||
654  !BaseRecord->isProvablyNotDerivedFrom(MemberRecord))
655  return false;
656  }
657 
658  DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS,
660  R.getLookupNameInfo());
661  return true;
662 }
663 
664 namespace {
665 
666 // Callback to only accept typo corrections that are either a ValueDecl or a
667 // FunctionTemplateDecl and are declared in the current record or, for a C++
668 // classes, one of its base classes.
669 class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback {
670 public:
671  explicit RecordMemberExprValidatorCCC(QualType RTy)
672  : Record(RTy->getAsRecordDecl()) {
673  // Don't add bare keywords to the consumer since they will always fail
674  // validation by virtue of not being associated with any decls.
675  WantTypeSpecifiers = false;
676  WantExpressionKeywords = false;
677  WantCXXNamedCasts = false;
678  WantFunctionLikeCasts = false;
679  WantRemainingKeywords = false;
680  }
681 
682  bool ValidateCandidate(const TypoCorrection &candidate) override {
683  NamedDecl *ND = candidate.getCorrectionDecl();
684  // Don't accept candidates that cannot be member functions, constants,
685  // variables, or templates.
686  if (!ND || !(isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)))
687  return false;
688 
689  // Accept candidates that occur in the current record.
690  if (Record->containsDecl(ND))
691  return true;
692 
693  if (const auto *RD = dyn_cast<CXXRecordDecl>(Record)) {
694  // Accept candidates that occur in any of the current class' base classes.
695  for (const auto &BS : RD->bases()) {
696  if (const auto *BSTy = BS.getType()->getAs<RecordType>()) {
697  if (BSTy->getDecl()->containsDecl(ND))
698  return true;
699  }
700  }
701  }
702 
703  return false;
704  }
705 
706  std::unique_ptr<CorrectionCandidateCallback> clone() override {
707  return std::make_unique<RecordMemberExprValidatorCCC>(*this);
708  }
709 
710 private:
711  const RecordDecl *const Record;
712 };
713 
714 }
715 
716 static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
717  Expr *BaseExpr, QualType RTy,
718  SourceLocation OpLoc, bool IsArrow,
719  CXXScopeSpec &SS, bool HasTemplateArgs,
720  SourceLocation TemplateKWLoc,
721  TypoExpr *&TE) {
722  SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
723  if (!RTy->isDependentType() &&
724  !SemaRef.isThisOutsideMemberFunctionBody(RTy) &&
725  SemaRef.RequireCompleteType(
726  OpLoc, RTy, diag::err_typecheck_incomplete_tag, BaseRange))
727  return true;
728 
729  // LookupTemplateName/LookupParsedName don't expect these both to exist
730  // simultaneously.
731  QualType ObjectType = SS.isSet() ? QualType() : RTy;
732  if (HasTemplateArgs || TemplateKWLoc.isValid())
733  return SemaRef.LookupTemplateName(R,
734  /*S=*/nullptr, SS, ObjectType,
735  /*EnteringContext=*/false, TemplateKWLoc);
736 
737  SemaRef.LookupParsedName(R, /*S=*/nullptr, &SS, ObjectType);
738 
740  return false;
741 
742  DeclarationName Typo = R.getLookupName();
743  SourceLocation TypoLoc = R.getNameLoc();
744  // Recompute the lookup context.
745  DeclContext *DC = SS.isSet() ? SemaRef.computeDeclContext(SS)
746  : SemaRef.computeDeclContext(RTy);
747 
748  struct QueryState {
749  Sema &SemaRef;
750  DeclarationNameInfo NameInfo;
751  Sema::LookupNameKind LookupKind;
752  RedeclarationKind Redecl;
753  };
754  QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
755  R.redeclarationKind()};
756  RecordMemberExprValidatorCCC CCC(RTy);
757  TE = SemaRef.CorrectTypoDelayed(
758  R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC,
759  [=, &SemaRef](const TypoCorrection &TC) {
760  if (TC) {
761  assert(!TC.isKeyword() &&
762  "Got a keyword as a correction for a member!");
763  bool DroppedSpecifier =
764  TC.WillReplaceSpecifier() &&
765  Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
766  SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
767  << Typo << DC << DroppedSpecifier
768  << SS.getRange());
769  } else {
770  SemaRef.Diag(TypoLoc, diag::err_no_member)
771  << Typo << DC << (SS.isSet() ? SS.getRange() : BaseRange);
772  }
773  },
774  [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
775  LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl);
776  R.clear(); // Ensure there's no decls lingering in the shared state.
777  R.suppressDiagnostics();
778  R.setLookupName(TC.getCorrection());
779  for (NamedDecl *ND : TC)
780  R.addDecl(ND);
781  R.resolveKind();
782  return SemaRef.BuildMemberReferenceExpr(
783  BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(),
784  nullptr, R, nullptr, nullptr);
785  },
787 
788  return false;
789 }
790 
792  ExprResult &BaseExpr, bool &IsArrow,
793  SourceLocation OpLoc, CXXScopeSpec &SS,
794  Decl *ObjCImpDecl, bool HasTemplateArgs,
795  SourceLocation TemplateKWLoc);
796 
798  Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
799  CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
800  NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
801  const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
802  ActOnMemberAccessExtraArgs *ExtraArgs) {
803  LookupResult R(*this, NameInfo, LookupMemberName);
804 
805  if (SS.isInvalid())
806  return ExprError();
807 
808  // Implicit member accesses.
809  if (!Base) {
810  TypoExpr *TE = nullptr;
811  QualType RecordTy = BaseType;
812  if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType();
813  if (LookupMemberExprInRecord(*this, R, nullptr, RecordTy, OpLoc, IsArrow,
814  SS, TemplateArgs != nullptr, TemplateKWLoc,
815  TE))
816  return ExprError();
817  if (TE)
818  return TE;
819 
820  // Explicit member accesses.
821  } else {
823  ExprResult Result =
824  LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS,
825  ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
826  TemplateArgs != nullptr, TemplateKWLoc);
827 
828  if (BaseResult.isInvalid())
829  return ExprError();
830  Base = BaseResult.get();
831 
832  if (Result.isInvalid())
833  return ExprError();
834 
835  if (Result.get())
836  return Result;
837 
838  // LookupMemberExpr can modify Base, and thus change BaseType
839  BaseType = Base->getType();
840  }
841 
842  return BuildMemberReferenceExpr(Base, BaseType,
843  OpLoc, IsArrow, SS, TemplateKWLoc,
844  FirstQualifierInScope, R, TemplateArgs, S,
845  false, ExtraArgs);
846 }
847 
850  SourceLocation loc,
851  IndirectFieldDecl *indirectField,
852  DeclAccessPair foundDecl,
853  Expr *baseObjectExpr,
854  SourceLocation opLoc) {
855  // First, build the expression that refers to the base object.
856 
857  // Case 1: the base of the indirect field is not a field.
858  VarDecl *baseVariable = indirectField->getVarDecl();
859  CXXScopeSpec EmptySS;
860  if (baseVariable) {
861  assert(baseVariable->getType()->isRecordType());
862 
863  // In principle we could have a member access expression that
864  // accesses an anonymous struct/union that's a static member of
865  // the base object's class. However, under the current standard,
866  // static data members cannot be anonymous structs or unions.
867  // Supporting this is as easy as building a MemberExpr here.
868  assert(!baseObjectExpr && "anonymous struct/union is static data member?");
869 
870  DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
871 
872  ExprResult result
873  = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
874  if (result.isInvalid()) return ExprError();
875 
876  baseObjectExpr = result.get();
877  }
878 
879  assert((baseVariable || baseObjectExpr) &&
880  "referencing anonymous struct/union without a base variable or "
881  "expression");
882 
883  // Build the implicit member references to the field of the
884  // anonymous struct/union.
885  Expr *result = baseObjectExpr;
887  FI = indirectField->chain_begin(), FEnd = indirectField->chain_end();
888 
889  // Case 2: the base of the indirect field is a field and the user
890  // wrote a member expression.
891  if (!baseVariable) {
892  FieldDecl *field = cast<FieldDecl>(*FI);
893 
894  bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType();
895 
896  // Make a nameInfo that properly uses the anonymous name.
897  DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
898 
899  // Build the first member access in the chain with full information.
900  result =
901  BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(),
902  SS, field, foundDecl, memberNameInfo)
903  .get();
904  if (!result)
905  return ExprError();
906  }
907 
908  // In all cases, we should now skip the first declaration in the chain.
909  ++FI;
910 
911  while (FI != FEnd) {
912  FieldDecl *field = cast<FieldDecl>(*FI++);
913 
914  // FIXME: these are somewhat meaningless
915  DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
916  DeclAccessPair fakeFoundDecl =
917  DeclAccessPair::make(field, field->getAccess());
918 
919  result =
920  BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(),
921  (FI == FEnd ? SS : EmptySS), field,
922  fakeFoundDecl, memberNameInfo)
923  .get();
924  }
925 
926  return result;
927 }
928 
929 static ExprResult
930 BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
931  const CXXScopeSpec &SS,
932  MSPropertyDecl *PD,
933  const DeclarationNameInfo &NameInfo) {
934  // Property names are always simple identifiers and therefore never
935  // require any interesting additional storage.
936  return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
939  NameInfo.getLoc());
940 }
941 
943  Expr *Base, bool IsArrow, SourceLocation OpLoc, NestedNameSpecifierLoc NNS,
944  SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
945  bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
947  const TemplateArgumentListInfo *TemplateArgs) {
948  assert((!IsArrow || Base->isPRValue()) &&
949  "-> base must be a pointer prvalue");
950  MemberExpr *E =
951  MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc,
952  Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty,
954  E->setHadMultipleCandidates(HadMultipleCandidates);
956 
957  // C++ [except.spec]p17:
958  // An exception-specification is considered to be needed when:
959  // - in an expression the function is the unique lookup result or the
960  // selected member of a set of overloaded functions
961  if (auto *FPT = Ty->getAs<FunctionProtoType>()) {
962  if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
963  if (auto *NewFPT = ResolveExceptionSpec(MemberNameInfo.getLoc(), FPT))
964  E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers()));
965  }
966  }
967 
968  return E;
969 }
970 
971 /// Determine if the given scope is within a function-try-block handler.
972 static bool IsInFnTryBlockHandler(const Scope *S) {
973  // Walk the scope stack until finding a FnTryCatchScope, or leave the
974  // function scope. If a FnTryCatchScope is found, check whether the TryScope
975  // flag is set. If it is not, it's a function-try-block handler.
976  for (; S != S->getFnParent(); S = S->getParent()) {
977  if (S->isFnTryCatchScope())
978  return (S->getFlags() & Scope::TryScope) != Scope::TryScope;
979  }
980  return false;
981 }
982 
985  SourceLocation OpLoc, bool IsArrow,
986  const CXXScopeSpec &SS,
987  SourceLocation TemplateKWLoc,
988  NamedDecl *FirstQualifierInScope,
989  LookupResult &R,
990  const TemplateArgumentListInfo *TemplateArgs,
991  const Scope *S,
992  bool SuppressQualifierCheck,
993  ActOnMemberAccessExtraArgs *ExtraArgs) {
994  assert(!SS.isInvalid() && "nested-name-specifier cannot be invalid");
995  // If the member wasn't found in the current instantiation, or if the
996  // arrow operator was used with a dependent non-pointer object expression,
997  // build a CXXDependentScopeMemberExpr.
999  (R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
1000  (SS.isSet() ? SS.getScopeRep()->isDependent()
1001  : BaseExprType->isDependentType())))
1002  return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
1003  TemplateKWLoc, FirstQualifierInScope,
1004  R.getLookupNameInfo(), TemplateArgs);
1005 
1006  QualType BaseType = BaseExprType;
1007  if (IsArrow) {
1008  assert(BaseType->isPointerType());
1009  BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1010  }
1011  R.setBaseObjectType(BaseType);
1012 
1013  assert((SS.isEmpty()
1014  ? !BaseType->isDependentType() || computeDeclContext(BaseType)
1016  "dependent lookup context that isn't the current instantiation?");
1017 
1018  // C++1z [expr.ref]p2:
1019  // For the first option (dot) the first expression shall be a glvalue [...]
1020  if (!IsArrow && BaseExpr && BaseExpr->isPRValue()) {
1021  ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
1022  if (Converted.isInvalid())
1023  return ExprError();
1024  BaseExpr = Converted.get();
1025  }
1026 
1027  const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
1028  DeclarationName MemberName = MemberNameInfo.getName();
1029  SourceLocation MemberLoc = MemberNameInfo.getLoc();
1030 
1031  if (R.isAmbiguous())
1032  return ExprError();
1033 
1034  // [except.handle]p10: Referring to any non-static member or base class of an
1035  // object in the handler for a function-try-block of a constructor or
1036  // destructor for that object results in undefined behavior.
1037  const auto *FD = getCurFunctionDecl();
1038  if (S && BaseExpr && FD &&
1039  (isa<CXXDestructorDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
1040  isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts()) &&
1042  Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr)
1043  << isa<CXXDestructorDecl>(FD);
1044 
1045  if (R.empty()) {
1046  ExprResult RetryExpr = ExprError();
1047  if (ExtraArgs && !IsArrow && BaseExpr && !BaseExpr->isTypeDependent()) {
1048  SFINAETrap Trap(*this, true);
1049  ParsedType ObjectType;
1050  bool MayBePseudoDestructor = false;
1051  RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr, OpLoc,
1052  tok::arrow, ObjectType,
1053  MayBePseudoDestructor);
1054  if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) {
1055  CXXScopeSpec TempSS(SS);
1056  RetryExpr = ActOnMemberAccessExpr(
1057  ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS,
1058  TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl);
1059  }
1060  if (Trap.hasErrorOccurred())
1061  RetryExpr = ExprError();
1062  }
1063 
1064  // Rederive where we looked up.
1065  DeclContext *DC =
1066  (SS.isSet() ? computeDeclContext(SS) : computeDeclContext(BaseType));
1067  assert(DC);
1068 
1069  if (RetryExpr.isUsable())
1070  Diag(OpLoc, diag::err_no_member_overloaded_arrow)
1071  << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->");
1072  else
1073  Diag(R.getNameLoc(), diag::err_no_member)
1074  << MemberName << DC
1075  << (SS.isSet()
1076  ? SS.getRange()
1077  : (BaseExpr ? BaseExpr->getSourceRange() : SourceRange()));
1078  return RetryExpr;
1079  }
1080 
1081  // Diagnose lookups that find only declarations from a non-base
1082  // type. This is possible for either qualified lookups (which may
1083  // have been qualified with an unrelated type) or implicit member
1084  // expressions (which were found with unqualified lookup and thus
1085  // may have come from an enclosing scope). Note that it's okay for
1086  // lookup to find declarations from a non-base type as long as those
1087  // aren't the ones picked by overload resolution.
1088  if ((SS.isSet() || !BaseExpr ||
1089  (isa<CXXThisExpr>(BaseExpr) &&
1090  cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
1091  !SuppressQualifierCheck &&
1092  CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
1093  return ExprError();
1094 
1095  // Construct an unresolved result if we in fact got an unresolved
1096  // result.
1097  if (R.isOverloadedResult() || R.isUnresolvableResult()) {
1098  // Suppress any lookup-related diagnostics; we'll do these when we
1099  // pick a member.
1100  R.suppressDiagnostics();
1101 
1102  UnresolvedMemberExpr *MemExpr
1104  BaseExpr, BaseExprType,
1105  IsArrow, OpLoc,
1107  TemplateKWLoc, MemberNameInfo,
1108  TemplateArgs, R.begin(), R.end());
1109 
1110  return MemExpr;
1111  }
1112 
1113  assert(R.isSingleResult());
1114  DeclAccessPair FoundDecl = R.begin().getPair();
1115  NamedDecl *MemberDecl = R.getFoundDecl();
1116 
1117  // FIXME: diagnose the presence of template arguments now.
1118 
1119  // If the decl being referenced had an error, return an error for this
1120  // sub-expr without emitting another error, in order to avoid cascading
1121  // error cases.
1122  if (MemberDecl->isInvalidDecl())
1123  return ExprError();
1124 
1125  // Handle the implicit-member-access case.
1126  if (!BaseExpr) {
1127  // If this is not an instance member, convert to a non-member access.
1128  if (!MemberDecl->isCXXInstanceMember()) {
1129  // We might have a variable template specialization (or maybe one day a
1130  // member concept-id).
1131  if (TemplateArgs || TemplateKWLoc.isValid())
1132  return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/false, TemplateArgs);
1133 
1134  return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl,
1135  FoundDecl, TemplateArgs);
1136  }
1138  if (SS.getRange().isValid())
1139  Loc = SS.getRange().getBegin();
1140  BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
1141  }
1142 
1143  // Check the use of this member.
1144  if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
1145  return ExprError();
1146 
1147  if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
1148  return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
1149  MemberNameInfo);
1150 
1151  if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
1152  return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
1153  MemberNameInfo);
1154 
1155  if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
1156  // We may have found a field within an anonymous union or struct
1157  // (C++ [class.union]).
1158  return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
1159  FoundDecl, BaseExpr,
1160  OpLoc);
1161 
1162  if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
1163  return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1164  SS.getWithLocInContext(Context), TemplateKWLoc, Var,
1165  FoundDecl, /*HadMultipleCandidates=*/false,
1166  MemberNameInfo, Var->getType().getNonReferenceType(),
1168  }
1169 
1170  if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
1171  ExprValueKind valueKind;
1172  QualType type;
1173  if (MemberFn->isInstance()) {
1174  valueKind = VK_PRValue;
1176  } else {
1177  valueKind = VK_LValue;
1178  type = MemberFn->getType();
1179  }
1180 
1181  return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1182  SS.getWithLocInContext(Context), TemplateKWLoc,
1183  MemberFn, FoundDecl, /*HadMultipleCandidates=*/false,
1184  MemberNameInfo, type, valueKind, OK_Ordinary);
1185  }
1186  assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
1187 
1188  if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
1189  return BuildMemberExpr(
1190  BaseExpr, IsArrow, OpLoc, SS.getWithLocInContext(Context),
1191  TemplateKWLoc, Enum, FoundDecl, /*HadMultipleCandidates=*/false,
1192  MemberNameInfo, Enum->getType(), VK_PRValue, OK_Ordinary);
1193  }
1194 
1195  if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
1196  if (!TemplateArgs) {
1197  diagnoseMissingTemplateArguments(TemplateName(VarTempl), MemberLoc);
1198  return ExprError();
1199  }
1200 
1201  DeclResult VDecl = CheckVarTemplateId(VarTempl, TemplateKWLoc,
1202  MemberNameInfo.getLoc(), *TemplateArgs);
1203  if (VDecl.isInvalid())
1204  return ExprError();
1205 
1206  // Non-dependent member, but dependent template arguments.
1207  if (!VDecl.get())
1208  return ActOnDependentMemberExpr(
1209  BaseExpr, BaseExpr->getType(), IsArrow, OpLoc, SS, TemplateKWLoc,
1210  FirstQualifierInScope, MemberNameInfo, TemplateArgs);
1211 
1212  VarDecl *Var = cast<VarDecl>(VDecl.get());
1213  if (!Var->getTemplateSpecializationKind())
1215 
1216  return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1217  SS.getWithLocInContext(Context), TemplateKWLoc, Var,
1218  FoundDecl, /*HadMultipleCandidates=*/false,
1219  MemberNameInfo, Var->getType().getNonReferenceType(),
1220  VK_LValue, OK_Ordinary, TemplateArgs);
1221  }
1222 
1223  // We found something that we didn't expect. Complain.
1224  if (isa<TypeDecl>(MemberDecl))
1225  Diag(MemberLoc, diag::err_typecheck_member_reference_type)
1226  << MemberName << BaseType << int(IsArrow);
1227  else
1228  Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
1229  << MemberName << BaseType << int(IsArrow);
1230 
1231  Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
1232  << MemberName;
1233  R.suppressDiagnostics();
1234  return ExprError();
1235 }
1236 
1237 /// Given that normal member access failed on the given expression,
1238 /// and given that the expression's type involves builtin-id or
1239 /// builtin-Class, decide whether substituting in the redefinition
1240 /// types would be profitable. The redefinition type is whatever
1241 /// this translation unit tried to typedef to id/Class; we store
1242 /// it to the side and then re-use it in places like this.
1244  const ObjCObjectPointerType *opty
1245  = base.get()->getType()->getAs<ObjCObjectPointerType>();
1246  if (!opty) return false;
1247 
1248  const ObjCObjectType *ty = opty->getObjectType();
1249 
1250  QualType redef;
1251  if (ty->isObjCId()) {
1252  redef = S.Context.getObjCIdRedefinitionType();
1253  } else if (ty->isObjCClass()) {
1255  } else {
1256  return false;
1257  }
1258 
1259  // Do the substitution as long as the redefinition type isn't just a
1260  // possibly-qualified pointer to builtin-id or builtin-Class again.
1261  opty = redef->getAs<ObjCObjectPointerType>();
1262  if (opty && !opty->getObjectType()->getInterface())
1263  return false;
1264 
1265  base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
1266  return true;
1267 }
1268 
1269 static bool isRecordType(QualType T) {
1270  return T->isRecordType();
1271 }
1273  if (const PointerType *PT = T->getAs<PointerType>())
1274  return PT->getPointeeType()->isRecordType();
1275  return false;
1276 }
1277 
1278 /// Perform conversions on the LHS of a member access expression.
1279 ExprResult
1281  if (IsArrow && !Base->getType()->isFunctionType())
1283 
1284  return CheckPlaceholderExpr(Base);
1285 }
1286 
1287 /// Look up the given member of the given non-type-dependent
1288 /// expression. This can return in one of two ways:
1289 /// * If it returns a sentinel null-but-valid result, the caller will
1290 /// assume that lookup was performed and the results written into
1291 /// the provided structure. It will take over from there.
1292 /// * Otherwise, the returned expression will be produced in place of
1293 /// an ordinary member expression.
1294 ///
1295 /// The ObjCImpDecl bit is a gross hack that will need to be properly
1296 /// fixed for ObjC++.
1298  ExprResult &BaseExpr, bool &IsArrow,
1299  SourceLocation OpLoc, CXXScopeSpec &SS,
1300  Decl *ObjCImpDecl, bool HasTemplateArgs,
1301  SourceLocation TemplateKWLoc) {
1302  assert(BaseExpr.get() && "no base expression");
1303 
1304  // Perform default conversions.
1305  BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
1306  if (BaseExpr.isInvalid())
1307  return ExprError();
1308 
1309  QualType BaseType = BaseExpr.get()->getType();
1310 
1311  DeclarationName MemberName = R.getLookupName();
1312  SourceLocation MemberLoc = R.getNameLoc();
1313 
1314  // For later type-checking purposes, turn arrow accesses into dot
1315  // accesses. The only access type we support that doesn't follow
1316  // the C equivalence "a->b === (*a).b" is ObjC property accesses,
1317  // and those never use arrows, so this is unaffected.
1318  if (IsArrow) {
1319  if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1320  BaseType = Ptr->getPointeeType();
1321  else if (const ObjCObjectPointerType *Ptr =
1322  BaseType->getAs<ObjCObjectPointerType>())
1323  BaseType = Ptr->getPointeeType();
1324  else if (BaseType->isFunctionType())
1325  goto fail;
1326  else if (BaseType->isDependentType())
1327  BaseType = S.Context.DependentTy;
1328  else if (BaseType->isRecordType()) {
1329  // Recover from arrow accesses to records, e.g.:
1330  // struct MyRecord foo;
1331  // foo->bar
1332  // This is actually well-formed in C++ if MyRecord has an
1333  // overloaded operator->, but that should have been dealt with
1334  // by now--or a diagnostic message already issued if a problem
1335  // was encountered while looking for the overloaded operator->.
1336  if (!S.getLangOpts().CPlusPlus) {
1337  S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1338  << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1339  << FixItHint::CreateReplacement(OpLoc, ".");
1340  }
1341  IsArrow = false;
1342  } else {
1343  S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
1344  << BaseType << BaseExpr.get()->getSourceRange();
1345  return ExprError();
1346  }
1347  }
1348 
1349  // If the base type is an atomic type, this access is undefined behavior per
1350  // C11 6.5.2.3p5. Instead of giving a typecheck error, we'll warn the user
1351  // about the UB and recover by converting the atomic lvalue into a non-atomic
1352  // lvalue. Because this is inherently unsafe as an atomic operation, the
1353  // warning defaults to an error.
1354  if (const auto *ATy = BaseType->getAs<AtomicType>()) {
1355  S.DiagRuntimeBehavior(OpLoc, nullptr,
1356  S.PDiag(diag::warn_atomic_member_access));
1357  BaseType = ATy->getValueType().getUnqualifiedType();
1358  BaseExpr = ImplicitCastExpr::Create(
1359  S.Context, IsArrow ? S.Context.getPointerType(BaseType) : BaseType,
1360  CK_AtomicToNonAtomic, BaseExpr.get(), nullptr,
1361  BaseExpr.get()->getValueKind(), FPOptionsOverride());
1362  }
1363 
1364  // Handle field access to simple records.
1365  if (BaseType->getAsRecordDecl()) {
1366  TypoExpr *TE = nullptr;
1367  if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow,
1368  SS, HasTemplateArgs, TemplateKWLoc, TE))
1369  return ExprError();
1370 
1371  // Returning valid-but-null is how we indicate to the caller that
1372  // the lookup result was filled in. If typo correction was attempted and
1373  // failed, the lookup result will have been cleared--that combined with the
1374  // valid-but-null ExprResult will trigger the appropriate diagnostics.
1375  return ExprResult(TE);
1376  } else if (BaseType->isDependentType()) {
1378  return ExprEmpty();
1379  }
1380 
1381  // Handle ivar access to Objective-C objects.
1382  if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
1383  if (!SS.isEmpty() && !SS.isInvalid()) {
1384  S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1385  << 1 << SS.getScopeRep()
1387  SS.clear();
1388  }
1389 
1390  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1391 
1392  // There are three cases for the base type:
1393  // - builtin id (qualified or unqualified)
1394  // - builtin Class (qualified or unqualified)
1395  // - an interface
1396  ObjCInterfaceDecl *IDecl = OTy->getInterface();
1397  if (!IDecl) {
1398  if (S.getLangOpts().ObjCAutoRefCount &&
1399  (OTy->isObjCId() || OTy->isObjCClass()))
1400  goto fail;
1401  // There's an implicit 'isa' ivar on all objects.
1402  // But we only actually find it this way on objects of type 'id',
1403  // apparently.
1404  if (OTy->isObjCId() && Member->isStr("isa"))
1405  return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1406  OpLoc, S.Context.getObjCClassType());
1407  if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1408  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1409  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1410  goto fail;
1411  }
1412 
1413  if (S.RequireCompleteType(OpLoc, BaseType,
1414  diag::err_typecheck_incomplete_tag,
1415  BaseExpr.get()))
1416  return ExprError();
1417 
1418  ObjCInterfaceDecl *ClassDeclared = nullptr;
1419  ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1420 
1421  if (!IV) {
1422  // Attempt to correct for typos in ivar names.
1423  DeclFilterCCC<ObjCIvarDecl> Validator{};
1424  Validator.IsObjCIvarLookup = IsArrow;
1425  if (TypoCorrection Corrected = S.CorrectTypo(
1426  R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
1427  Validator, Sema::CTK_ErrorRecovery, IDecl)) {
1428  IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
1429  S.diagnoseTypo(
1430  Corrected,
1431  S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1432  << IDecl->getDeclName() << MemberName);
1433 
1434  // Figure out the class that declares the ivar.
1435  assert(!ClassDeclared);
1436 
1437  Decl *D = cast<Decl>(IV->getDeclContext());
1438  if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1439  D = Category->getClassInterface();
1440 
1441  if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1442  ClassDeclared = Implementation->getClassInterface();
1443  else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1444  ClassDeclared = Interface;
1445 
1446  assert(ClassDeclared && "cannot query interface");
1447  } else {
1448  if (IsArrow &&
1449  IDecl->FindPropertyDeclaration(
1451  S.Diag(MemberLoc, diag::err_property_found_suggest)
1452  << Member << BaseExpr.get()->getType()
1453  << FixItHint::CreateReplacement(OpLoc, ".");
1454  return ExprError();
1455  }
1456 
1457  S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1458  << IDecl->getDeclName() << MemberName
1459  << BaseExpr.get()->getSourceRange();
1460  return ExprError();
1461  }
1462  }
1463 
1464  assert(ClassDeclared);
1465 
1466  // If the decl being referenced had an error, return an error for this
1467  // sub-expr without emitting another error, in order to avoid cascading
1468  // error cases.
1469  if (IV->isInvalidDecl())
1470  return ExprError();
1471 
1472  // Check whether we can reference this field.
1473  if (S.DiagnoseUseOfDecl(IV, MemberLoc))
1474  return ExprError();
1475  if (IV->getAccessControl() != ObjCIvarDecl::Public &&
1477  ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1478  if (ObjCMethodDecl *MD = S.getCurMethodDecl())
1479  ClassOfMethodDecl = MD->getClassInterface();
1480  else if (ObjCImpDecl && S.getCurFunctionDecl()) {
1481  // Case of a c-function declared inside an objc implementation.
1482  // FIXME: For a c-style function nested inside an objc implementation
1483  // class, there is no implementation context available, so we pass
1484  // down the context as argument to this routine. Ideally, this context
1485  // need be passed down in the AST node and somehow calculated from the
1486  // AST for a function decl.
1487  if (ObjCImplementationDecl *IMPD =
1488  dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1489  ClassOfMethodDecl = IMPD->getClassInterface();
1490  else if (ObjCCategoryImplDecl* CatImplClass =
1491  dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1492  ClassOfMethodDecl = CatImplClass->getClassInterface();
1493  }
1494  if (!S.getLangOpts().DebuggerSupport) {
1495  if (IV->getAccessControl() == ObjCIvarDecl::Private) {
1496  if (!declaresSameEntity(ClassDeclared, IDecl) ||
1497  !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
1498  S.Diag(MemberLoc, diag::err_private_ivar_access)
1499  << IV->getDeclName();
1500  } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1501  // @protected
1502  S.Diag(MemberLoc, diag::err_protected_ivar_access)
1503  << IV->getDeclName();
1504  }
1505  }
1506  bool warn = true;
1507  if (S.getLangOpts().ObjCWeak) {
1508  Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1509  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1510  if (UO->getOpcode() == UO_Deref)
1511  BaseExp = UO->getSubExpr()->IgnoreParenCasts();
1512 
1513  if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
1514  if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1515  S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
1516  warn = false;
1517  }
1518  }
1519  if (warn) {
1520  if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
1521  ObjCMethodFamily MF = MD->getMethodFamily();
1522  warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
1523  !S.ObjC().IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
1524  }
1525  if (warn)
1526  S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
1527  }
1528 
1529  ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
1530  IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1531  IsArrow);
1532 
1533  if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1534  if (!S.isUnevaluatedContext() &&
1535  !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1536  S.getCurFunction()->recordUseOfWeak(Result);
1537  }
1538 
1539  return Result;
1540  }
1541 
1542  // Objective-C property access.
1543  const ObjCObjectPointerType *OPT;
1544  if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
1545  if (!SS.isEmpty() && !SS.isInvalid()) {
1546  S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1547  << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
1548  SS.clear();
1549  }
1550 
1551  // This actually uses the base as an r-value.
1552  BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
1553  if (BaseExpr.isInvalid())
1554  return ExprError();
1555 
1556  assert(S.Context.hasSameUnqualifiedType(BaseType,
1557  BaseExpr.get()->getType()));
1558 
1559  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1560 
1561  const ObjCObjectType *OT = OPT->getObjectType();
1562 
1563  // id, with and without qualifiers.
1564  if (OT->isObjCId()) {
1565  // Check protocols on qualified interfaces.
1567  if (Decl *PMDecl =
1568  FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
1569  if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1570  // Check the use of this declaration
1571  if (S.DiagnoseUseOfDecl(PD, MemberLoc))
1572  return ExprError();
1573 
1574  return new (S.Context)
1576  OK_ObjCProperty, MemberLoc, BaseExpr.get());
1577  }
1578 
1579  if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
1580  Selector SetterSel =
1582  S.PP.getSelectorTable(),
1583  Member);
1584  ObjCMethodDecl *SMD = nullptr;
1585  if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
1586  /*Property id*/ nullptr,
1587  SetterSel, S.Context))
1588  SMD = dyn_cast<ObjCMethodDecl>(SDecl);
1589 
1590  return new (S.Context)
1592  OK_ObjCProperty, MemberLoc, BaseExpr.get());
1593  }
1594  }
1595  // Use of id.member can only be for a property reference. Do not
1596  // use the 'id' redefinition in this case.
1597  if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1598  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1599  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1600 
1601  return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1602  << MemberName << BaseType);
1603  }
1604 
1605  // 'Class', unqualified only.
1606  if (OT->isObjCClass()) {
1607  // Only works in a method declaration (??!).
1608  ObjCMethodDecl *MD = S.getCurMethodDecl();
1609  if (!MD) {
1610  if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1611  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1612  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1613 
1614  goto fail;
1615  }
1616 
1617  // Also must look for a getter name which uses property syntax.
1619  ObjCInterfaceDecl *IFace = MD->getClassInterface();
1620  if (!IFace)
1621  goto fail;
1622 
1623  ObjCMethodDecl *Getter;
1624  if ((Getter = IFace->lookupClassMethod(Sel))) {
1625  // Check the use of this method.
1626  if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
1627  return ExprError();
1628  } else
1629  Getter = IFace->lookupPrivateMethod(Sel, false);
1630  // If we found a getter then this may be a valid dot-reference, we
1631  // will look for the matching setter, in case it is needed.
1632  Selector SetterSel =
1634  S.PP.getSelectorTable(),
1635  Member);
1636  ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1637  if (!Setter) {
1638  // If this reference is in an @implementation, also check for 'private'
1639  // methods.
1640  Setter = IFace->lookupPrivateMethod(SetterSel, false);
1641  }
1642 
1643  if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
1644  return ExprError();
1645 
1646  if (Getter || Setter) {
1647  return new (S.Context) ObjCPropertyRefExpr(
1648  Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1649  OK_ObjCProperty, MemberLoc, BaseExpr.get());
1650  }
1651 
1652  if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1653  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1654  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1655 
1656  return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1657  << MemberName << BaseType);
1658  }
1659 
1660  // Normal property access.
1661  return S.ObjC().HandleExprPropertyRefExpr(
1662  OPT, BaseExpr.get(), OpLoc, MemberName, MemberLoc, SourceLocation(),
1663  QualType(), false);
1664  }
1665 
1666  if (BaseType->isExtVectorBoolType()) {
1667  // We disallow element access for ext_vector_type bool. There is no way to
1668  // materialize a reference to a vector element as a pointer (each element is
1669  // one bit in the vector).
1670  S.Diag(R.getNameLoc(), diag::err_ext_vector_component_name_illegal)
1671  << MemberName
1672  << (BaseExpr.get() ? BaseExpr.get()->getSourceRange() : SourceRange());
1673  return ExprError();
1674  }
1675 
1676  // Handle 'field access' to vectors, such as 'V.xx'.
1677  if (BaseType->isExtVectorType()) {
1678  // FIXME: this expr should store IsArrow.
1679  IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1680  ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
1681  QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
1682  Member, MemberLoc);
1683  if (ret.isNull())
1684  return ExprError();
1685  Qualifiers BaseQ =
1686  S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers();
1687  ret = S.Context.getQualifiedType(ret, BaseQ);
1688 
1689  return new (S.Context)
1690  ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
1691  }
1692 
1693  // Adjust builtin-sel to the appropriate redefinition type if that's
1694  // not just a pointer to builtin-sel again.
1695  if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
1697  BaseExpr = S.ImpCastExprToType(
1698  BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1699  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1700  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1701  }
1702 
1703  // Failure cases.
1704  fail:
1705 
1706  // Recover from dot accesses to pointers, e.g.:
1707  // type *foo;
1708  // foo.bar
1709  // This is actually well-formed in two cases:
1710  // - 'type' is an Objective C type
1711  // - 'bar' is a pseudo-destructor name which happens to refer to
1712  // the appropriate pointer type
1713  if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1714  if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
1716  S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1717  << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1718  << FixItHint::CreateReplacement(OpLoc, "->");
1719 
1720  if (S.isSFINAEContext())
1721  return ExprError();
1722 
1723  // Recurse as an -> access.
1724  IsArrow = true;
1725  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1726  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1727  }
1728  }
1729 
1730  // If the user is trying to apply -> or . to a function name, it's probably
1731  // because they forgot parentheses to call that function.
1732  if (S.tryToRecoverWithCall(
1733  BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1734  /*complain*/ false,
1735  IsArrow ? &isPointerToRecordType : &isRecordType)) {
1736  if (BaseExpr.isInvalid())
1737  return ExprError();
1738  BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1739  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1740  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1741  }
1742 
1743  // HLSL supports implicit conversion of scalar types to single element vector
1744  // rvalues in member expressions.
1745  if (S.getLangOpts().HLSL && BaseType->isScalarType()) {
1746  QualType VectorTy = S.Context.getExtVectorType(BaseType, 1);
1747  BaseExpr = S.ImpCastExprToType(BaseExpr.get(), VectorTy, CK_VectorSplat,
1748  BaseExpr.get()->getValueKind());
1749  return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, ObjCImpDecl,
1750  HasTemplateArgs, TemplateKWLoc);
1751  }
1752 
1753  S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
1754  << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
1755 
1756  return ExprError();
1757 }
1758 
1759 /// The main callback when the parser finds something like
1760 /// expression . [nested-name-specifier] identifier
1761 /// expression -> [nested-name-specifier] identifier
1762 /// where 'identifier' encompasses a fairly broad spectrum of
1763 /// possibilities, including destructor and operator references.
1764 ///
1765 /// \param OpKind either tok::arrow or tok::period
1766 /// \param ObjCImpDecl the current Objective-C \@implementation
1767 /// decl; this is an ugly hack around the fact that Objective-C
1768 /// \@implementations aren't properly put in the context chain
1770  SourceLocation OpLoc,
1771  tok::TokenKind OpKind,
1772  CXXScopeSpec &SS,
1773  SourceLocation TemplateKWLoc,
1774  UnqualifiedId &Id,
1775  Decl *ObjCImpDecl) {
1776  if (SS.isSet() && SS.isInvalid())
1777  return ExprError();
1778 
1779  // Warn about the explicit constructor calls Microsoft extension.
1780  if (getLangOpts().MicrosoftExt &&
1782  Diag(Id.getSourceRange().getBegin(),
1783  diag::ext_ms_explicit_constructor_call);
1784 
1785  TemplateArgumentListInfo TemplateArgsBuffer;
1786 
1787  // Decompose the name into its component parts.
1788  DeclarationNameInfo NameInfo;
1789  const TemplateArgumentListInfo *TemplateArgs;
1790  DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1791  NameInfo, TemplateArgs);
1792 
1793  bool IsArrow = (OpKind == tok::arrow);
1794 
1795  if (getLangOpts().HLSL && IsArrow)
1796  return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 2);
1797 
1798  NamedDecl *FirstQualifierInScope
1799  = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
1800 
1801  // This is a postfix expression, so get rid of ParenListExprs.
1803  if (Result.isInvalid()) return ExprError();
1804  Base = Result.get();
1805 
1806  ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
1808  Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc,
1809  FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs);
1810 
1811  if (!Res.isInvalid() && isa<MemberExpr>(Res.get()))
1812  CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get()));
1813 
1814  return Res;
1815 }
1816 
1817 void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
1818  if (isUnevaluatedContext())
1819  return;
1820 
1821  QualType ResultTy = E->getType();
1822 
1823  // Member accesses have four cases:
1824  // 1: non-array member via "->": dereferences
1825  // 2: non-array member via ".": nothing interesting happens
1826  // 3: array member access via "->": nothing interesting happens
1827  // (this returns an array lvalue and does not actually dereference memory)
1828  // 4: array member access via ".": *adds* a layer of indirection
1829  if (ResultTy->isArrayType()) {
1830  if (!E->isArrow()) {
1831  // This might be something like:
1832  // (*structPtr).arrayMember
1833  // which behaves roughly like:
1834  // &(*structPtr).pointerMember
1835  // in that the apparent dereference in the base expression does not
1836  // actually happen.
1837  CheckAddressOfNoDeref(E->getBase());
1838  }
1839  } else if (E->isArrow()) {
1840  if (const auto *Ptr = dyn_cast<PointerType>(
1842  if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
1843  ExprEvalContexts.back().PossibleDerefs.insert(E);
1844  }
1845  }
1846 }
1847 
1848 ExprResult
1849 Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1850  SourceLocation OpLoc, const CXXScopeSpec &SS,
1851  FieldDecl *Field, DeclAccessPair FoundDecl,
1852  const DeclarationNameInfo &MemberNameInfo) {
1853  // x.a is an l-value if 'a' has a reference type. Otherwise:
1854  // x.a is an l-value/x-value/pr-value if the base is (and note
1855  // that *x is always an l-value), except that if the base isn't
1856  // an ordinary object then we must have an rvalue.
1857  ExprValueKind VK = VK_LValue;
1859  if (!IsArrow) {
1860  if (BaseExpr->getObjectKind() == OK_Ordinary)
1861  VK = BaseExpr->getValueKind();
1862  else
1863  VK = VK_PRValue;
1864  }
1865  if (VK != VK_PRValue && Field->isBitField())
1866  OK = OK_BitField;
1867 
1868  // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1869  QualType MemberType = Field->getType();
1870  if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1871  MemberType = Ref->getPointeeType();
1872  VK = VK_LValue;
1873  } else {
1874  QualType BaseType = BaseExpr->getType();
1875  if (IsArrow) BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1876 
1877  Qualifiers BaseQuals = BaseType.getQualifiers();
1878 
1879  // GC attributes are never picked up by members.
1880  BaseQuals.removeObjCGCAttr();
1881 
1882  // CVR attributes from the base are picked up by members,
1883  // except that 'mutable' members don't pick up 'const'.
1884  if (Field->isMutable()) BaseQuals.removeConst();
1885 
1886  Qualifiers MemberQuals =
1887  Context.getCanonicalType(MemberType).getQualifiers();
1888 
1889  assert(!MemberQuals.hasAddressSpace());
1890 
1891  Qualifiers Combined = BaseQuals + MemberQuals;
1892  if (Combined != MemberQuals)
1893  MemberType = Context.getQualifiedType(MemberType, Combined);
1894 
1895  // Pick up NoDeref from the base in case we end up using AddrOf on the
1896  // result. E.g. the expression
1897  // &someNoDerefPtr->pointerMember
1898  // should be a noderef pointer again.
1899  if (BaseType->hasAttr(attr::NoDeref))
1900  MemberType =
1901  Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
1902  }
1903 
1904  auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
1905  if (!(CurMethod && CurMethod->isDefaulted()))
1906  UnusedPrivateFields.remove(Field);
1907 
1909  FoundDecl, Field);
1910  if (Base.isInvalid())
1911  return ExprError();
1912 
1913  // Build a reference to a private copy for non-static data members in
1914  // non-static member functions, privatized by OpenMP constructs.
1915  if (getLangOpts().OpenMP && IsArrow &&
1917  isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
1918  if (auto *PrivateCopy = OpenMP().isOpenMPCapturedDecl(Field)) {
1919  return OpenMP().getOpenMPCapturedExpr(PrivateCopy, VK, OK,
1920  MemberNameInfo.getLoc());
1921  }
1922  }
1923 
1924  return BuildMemberExpr(
1925  Base.get(), IsArrow, OpLoc, SS.getWithLocInContext(Context),
1926  /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1927  /*HadMultipleCandidates=*/false, MemberNameInfo, MemberType, VK, OK);
1928 }
1929 
1930 /// Builds an implicit member access expression. The current context
1931 /// is known to be an instance method, and the given unqualified lookup
1932 /// set is known to contain only instance members, at least one of which
1933 /// is from an appropriate type.
1934 ExprResult
1936  SourceLocation TemplateKWLoc,
1937  LookupResult &R,
1938  const TemplateArgumentListInfo *TemplateArgs,
1939  bool IsKnownInstance, const Scope *S) {
1940  assert(!R.empty() && !R.isAmbiguous());
1941 
1942  SourceLocation loc = R.getNameLoc();
1943 
1944  // If this is known to be an instance access, go ahead and build an
1945  // implicit 'this' expression now.
1946  QualType ThisTy = getCurrentThisType();
1947  assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
1948 
1949  Expr *baseExpr = nullptr; // null signifies implicit access
1950  if (IsKnownInstance) {
1952  if (SS.getRange().isValid())
1953  Loc = SS.getRange().getBegin();
1954  baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
1955  }
1956 
1957  return BuildMemberReferenceExpr(
1958  baseExpr, ThisTy,
1959  /*OpLoc=*/SourceLocation(),
1960  /*IsArrow=*/!getLangOpts().HLSL, SS, TemplateKWLoc,
1961  /*FirstQualifierInScope=*/nullptr, R, TemplateArgs, S);
1962 }
int Id
Definition: ASTDiff.cpp:190
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
int Category
Definition: Format.cpp:2979
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Preprocessor interface.
RedeclarationKind
Specifies whether (or how) name lookup is being performed for a redeclaration (vs.
Definition: Redeclaration.h:18
static RecordDecl * getAsRecordDecl(QualType BaseType)
static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base)
Given that normal member access failed on the given expression, and given that the expression's type ...
static bool isPointerToRecordType(QualType T)
IMAKind
@ IMA_Mixed_Unrelated
The reference may be to an instance member, but it is invalid if so, because the context is from an u...
@ IMA_Mixed
The reference may be an implicit instance member access.
@ IMA_Error_Unrelated
All possible referrents are instance members of an unrelated class.
@ IMA_Unresolved
The reference may be to an unresolved using declaration.
@ IMA_Abstract
The reference is a contextually-permitted abstract member reference.
@ IMA_Mixed_StaticOrExplicitContext
The reference may be to an instance member, but it might be invalid if so, because the context is not...
@ IMA_Instance
The reference is definitely an implicit instance member access.
@ IMA_Error_StaticOrExplicitContext
All possible referrents are instance members and the current context is not an instance method.
@ IMA_Unresolved_StaticOrExplicitContext
The reference may be to an unresolved using declaration and the context is not an instance method.
@ IMA_Dependent
Whether the context is static is dependent on the enclosing template (i.e.
@ IMA_Field_Uneval_Context
@ IMA_Static
The reference is definitely not an instance member access.
static Decl * FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl *PDecl, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record, const BaseSet &Bases)
Determines if the given class is provably not derived from all of the prospective base classes.
static void diagnoseInstanceReference(Sema &SemaRef, const CXXScopeSpec &SS, NamedDecl *Rep, const DeclarationNameInfo &nameInfo)
Diagnose a reference to a field with no object available.
static bool isRecordType(QualType T)
static QualType CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK, SourceLocation OpLoc, const IdentifierInfo *CompName, SourceLocation CompLoc)
Check an ext-vector component access expression.
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > BaseSet
static void DiagnoseQualifiedMemberReference(Sema &SemaRef, Expr *BaseExpr, QualType BaseType, const CXXScopeSpec &SS, NamedDecl *rep, const DeclarationNameInfo &nameInfo)
We know that the given qualified member reference points only to declarations which do not belong to ...
static bool IsValidOpenCLComponentSwizzleLength(unsigned len)
static ExprResult BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, const CXXScopeSpec &SS, MSPropertyDecl *PD, const DeclarationNameInfo &NameInfo)
static bool IsRGBA(char c)
Determine whether input char is from rgba component set.
static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, Expr *BaseExpr, QualType RTy, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, bool HasTemplateArgs, SourceLocation TemplateKWLoc, TypoExpr *&TE)
static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, const LookupResult &R)
The given lookup names class member(s) and is not being used for an address-of-member expression.
static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, Decl *ObjCImpDecl, bool HasTemplateArgs, SourceLocation TemplateKWLoc)
Look up the given member of the given non-type-dependent expression.
static Decl * FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
static bool IsInFnTryBlockHandler(const Scope *S)
Determine if the given scope is within a function-try-block handler.
SourceRange Range
Definition: SemaObjC.cpp:754
SourceLocation Loc
Definition: SemaObjC.cpp:755
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
__device__ int
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
QualType getObjCClassType() const
Represents the Objective-C Class type.
Definition: ASTContext.h:2100
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2589
QualType getObjCSelRedefinitionType() const
Retrieve the type that 'SEL' has been defined to, which may be different from the built-in 'SEL' if '...
Definition: ASTContext.h:1905
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType DependentTy
Definition: ASTContext.h:1122
CanQualType BoundMemberTy
Definition: ASTContext.h:1122
CanQualType PseudoObjectTy
Definition: ASTContext.h:1125
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2171
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2632
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
Definition: ASTContext.h:1892
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
Definition: ASTContext.h:1879
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
bool isUsable() const
Definition: Ownership.h:168
static CXXDependentScopeMemberExpr * Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs)
Definition: ExprCXX.cpp:1484
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
Definition: DeclCXX.cpp:2455
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2186
bool isStatic() const
Definition: DeclCXX.cpp:2186
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is provably not derived from the type Base.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:523
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:95
SourceRange getRange() const
Definition: DeclSpec.h:80
bool isSet() const
Deprecated.
Definition: DeclSpec.h:228
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:152
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:213
bool isEmpty() const
No scope specifier.
Definition: DeclSpec.h:208
Qualifiers getQualifiers() const
Retrieve all qualifiers.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition: DeclBase.h:2191
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1282
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2066
bool isRecord() const
Definition: DeclBase.h:2146
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1352
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1363
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInvalidDecl() const
Definition: DeclBase.h:594
SourceLocation getLocation() const
Definition: DeclBase.h:445
AccessSpecifier getAccess() const
Definition: DeclBase.h:513
DeclContext * getDeclContext()
Definition: DeclBase.h:454
The name of a declaration.
bool isDependentName() const
Determines whether the name itself is dependent, e.g., because it involves a C++ type that is itself ...
std::string getAsString() const
Retrieve the human-readable string for this name.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
NameKind getNameKind() const
Determine what kind of name this is.
bool isEmpty() const
Evaluates true when this declaration name is empty.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:922
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3300
This represents one expression.
Definition: Expr.h:110
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3116
void setType(QualType t)
Definition: Expr.h:143
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition: Expr.h:437
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:192
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3111
bool isPRValue() const
Definition: Expr.h:278
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:444
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3091
QualType getType() const
Definition: Expr.h:142
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition: Expr.h:6154
ExtVectorType - Extended vector type.
Definition: Type.h:4073
bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const
Definition: Type.h:4126
static int getNumericAccessorIdx(char c)
Definition: Type.h:4091
static int getPointAccessorIdx(char c)
Definition: Type.h:4081
Represents difference between two FPOptions values.
Definition: LangOptions.h:956
Represents a member of a struct/union/class.
Definition: Decl.h:3060
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Definition: Diagnostic.h:135
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition: Diagnostic.h:124
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition: Diagnostic.h:98
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2709
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4668
One of these records is kept for each identifier that is lexed.
unsigned getLength() const
Efficiently return the length of this identifier info.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition: Expr.cpp:2129
Represents a field injected from an anonymous union/struct into the parent scope.
Definition: Decl.h:3344
chain_iterator chain_end() const
Definition: Decl.h:3370
chain_iterator chain_begin() const
Definition: Decl.h:3369
ArrayRef< NamedDecl * >::const_iterator chain_iterator
Definition: Decl.h:3364
VarDecl * getVarDecl() const
Definition: Decl.h:3379
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
iterator begin(Source *source, bool LocalOnly=false)
Represents the results of name lookup.
Definition: Lookup.h:46
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:575
RedeclarationKind redeclarationKind() const
Definition: Lookup.h:290
bool wasNotFoundInCurrentInstantiation() const
Determine whether no result was found because we could not search into dependent base classes of the ...
Definition: Lookup.h:495
bool isUnresolvableResult() const
Definition: Lookup.h:340
void setBaseObjectType(QualType T)
Sets the base object type for this lookup.
Definition: Lookup.h:469
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:362
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
Definition: Lookup.h:452
bool isOverloadedResult() const
Determines if the results are overloaded.
Definition: Lookup.h:336
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:664
bool isAmbiguous() const
Definition: Lookup.h:324
Sema & getSema() const
Get the Sema object that this lookup result is searching with.
Definition: Lookup.h:670
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:568
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:331
Sema::LookupNameKind getLookupKind() const
Gets the kind of lookup to perform.
Definition: Lookup.h:275
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:634
DeclarationName getLookupName() const
Gets the name to look up.
Definition: Lookup.h:265
iterator end() const
Definition: Lookup.h:359
void setNotFoundInCurrentInstantiation()
Note that while no result was found in the current instantiation, there were dependent base classes t...
Definition: Lookup.h:501
iterator begin() const
Definition: Lookup.h:358
const DeclarationNameInfo & getLookupNameInfo() const
Gets the name info to look up.
Definition: Lookup.h:255
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:4235
A member reference to an MSPropertyDecl.
Definition: ExprCXX.h:929
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3224
void setHadMultipleCandidates(bool V=true)
Sets the flag telling whether this expression refers to a method that was resolved from an overloaded...
Definition: Expr.h:3434
static MemberExpr * Create(const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR)
Definition: Expr.cpp:1809
Expr * getBase() const
Definition: Expr.h:3301
bool isArrow() const
Definition: Expr.h:3408
This represents a decl that may have a name.
Definition: Decl.h:249
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:463
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition: Decl.cpp:1963
bool isCXXClassMember() const
Determine whether this declaration is a C++ class member.
Definition: Decl.h:373
A C++ nested-name-specifier augmented with source location information.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition: DeclObjC.cpp:250
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition: DeclObjC.h:1065
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2594
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:637
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
Definition: DeclObjC.h:1850
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition: DeclObjC.cpp:756
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition: DeclObjC.h:1808
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition: ExprObjC.h:1491
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1950
AccessControl getAccessControl() const
Definition: DeclObjC.h:1998
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
Definition: DeclObjC.cpp:1899
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:549
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1211
Represents a pointer to an Objective C object.
Definition: Type.h:7020
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Definition: Type.h:7057
qual_range quals() const
Definition: Type.h:7139
Represents a class type in Objective C.
Definition: Type.h:6766
bool isObjCClass() const
Definition: Type.h:6834
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Definition: Type.h:6999
bool isObjCId() const
Definition: Type.h:6830
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:617
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
protocol_range protocols() const
Definition: DeclObjC.h:2158
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3151
QualType getPointeeType() const
Definition: Type.h:3161
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
A (possibly-)qualified type.
Definition: Type.h:940
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition: Type.h:1291
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7411
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1432
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:7572
The collection of all-type qualifiers we support.
Definition: Type.h:318
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition: Type.h:350
bool hasAddressSpace() const
Definition: Type.h:556
void removeObjCGCAttr()
Definition: Type.h:509
void removeConst()
Definition: Type.h:445
Represents a struct/union/class.
Definition: Decl.h:4171
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5561
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3392
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
@ TryScope
This is the scope of a C++ try statement.
Definition: Scope.h:105
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Selector getNullarySelector(const IdentifierInfo *ID)
Smart pointer class that efficiently represents Objective-C method names.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:57
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
bool IvarBacksCurrentMethodAccessor(ObjCInterfaceDecl *IFace, ObjCMethodDecl *Method, ObjCIvarDecl *IV)
IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is an ivar synthesized for 'Meth...
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition: Sema.h:9610
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:9640
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:462
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
SemaObjC & ObjC()
Definition: Sema.h:1012
ExprResult 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=nullptr)
NamedDecl * FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS)
If the given nested-name-specifier begins with a bare identifier (e.g., Base::), perform name lookup ...
LookupNameKind
Describes the kind of name lookup to perform.
Definition: Sema.h:7483
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:7495
bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, bool EnteringContext, RequiredTemplateKind RequiredTemplate=SourceLocation(), AssumedTemplateKind *ATK=nullptr, bool AllowTypoCorrection=true)
void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *&TemplateArgs)
Decomposes the given name into a DeclarationNameInfo, its location, and possibly a list of template a...
Definition: SemaExpr.cpp:2422
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
ExtVectorDeclsType ExtVectorDecls
ExtVectorDecls - This is a list all the extended vector types.
Definition: Sema.h:3578
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1547
ASTContext & Context
Definition: Sema.h:857
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow)
Perform conversions on the LHS of a member access expression.
ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME)
This is not an AltiVec-style cast or or C++ direct-initialization, so turn the ParenListExpr into a s...
Definition: SemaExpr.cpp:8003
bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD, bool ForceComplain=false, bool(*IsPlausibleResult)(QualType)=nullptr)
Try to recover by turning the given expression into a call.
Definition: Sema.cpp:2747
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:833
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:697
ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo *TemplateArgs)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
Definition: Sema.cpp:678
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition: Sema.cpp:1552
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
TypoExpr * CorrectTypoDelayed(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D)
If D cannot be odr-used in the current expression evaluation context, return a reason explaining why.
Definition: SemaExpr.cpp:2325
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, QualType ObjectType, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
Preprocessor & PP
Definition: Sema.h:856
bool isPotentialImplicitMemberAccess(const CXXScopeSpec &SS, LookupResult &R, bool IsAddressOfOperand)
Check whether an expression might be an implicit class member access.
const LangOptions & getLangOpts() const
Definition: Sema.h:519
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
Definition: SemaInit.cpp:8548
NamedDeclSetType UnusedPrivateFields
Set containing all declared private fields that are not used.
Definition: Sema.h:4938
Expr * BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit)
Build a CXXThisExpr and mark it referenced in the current context.
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, bool IsDefiniteInstance, const Scope *S)
Builds an implicit member access expression.
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:721
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
Definition: SemaExpr.cpp:3301
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:995
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
Definition: Sema.h:6408
DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const
If AllowLambda is true, treat lambda as function.
Definition: Sema.cpp:1527
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20867
QualType CXXThisTypeOverride
When non-NULL, the C++ 'this' expression is allowed despite the current context not being a non-stati...
Definition: Sema.h:6670
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs)
DeclResult CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, SourceLocation TemplateNameLoc, const TemplateArgumentListInfo &TemplateArgs)
Get the specialization of the given variable template corresponding to the specified argument list,...
bool isThisOutsideMemberFunctionBody(QualType BaseType)
Determine whether the given type is the type of *this that is used outside of the body of a member fu...
ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, const Scope *S)
Builds an expression which might be an implicit member expression.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
Definition: SemaExpr.cpp:20145
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
Definition: SemaExpr.cpp:229
SemaHLSL & HLSL()
Definition: Sema.h:1007
@ CTK_ErrorRecovery
Definition: Sema.h:7727
ExternalSemaSource * getExternalSource() const
Definition: Sema.h:529
@ UnevaluatedAbstract
The current expression occurs within an unevaluated operand that unconditionally permits abstract ref...
@ UnevaluatedList
The current expression occurs within a braced-init-list within an unevaluated operand.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ DiscardedStatement
The current expression occurs within a discarded statement.
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8923
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
Definition: Sema.h:6558
bool isDependentScopeSpecifier(const CXXScopeSpec &SS)
DiagnosticsEngine & Diags
Definition: Sema.h:859
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition: SemaExpr.cpp:597
void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc)
SemaOpenMP & OpenMP()
Definition: Sema.h:1022
MemberExpr * 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=nullptr)
void MarkMemberReferenced(MemberExpr *E)
Perform reference-marking and odr-use handling for a MemberExpr.
Definition: SemaExpr.cpp:19921
ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member)
Cast a base object to a member's actual type.
Definition: SemaExpr.cpp:3081
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:891
bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, const CXXScopeSpec &SS, const LookupResult &R)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
bool isValid() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
bool hasAttr(attr::Kind AK) const
Determine whether this type had the specified attribute applied to it (looking through top-level type...
Definition: Type.cpp:1898
bool isArrayType() const
Definition: Type.h:7690
bool isPointerType() const
Definition: Type.h:7624
bool isObjCSelType() const
Definition: Type.h:7805
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8227
bool isScalarType() const
Definition: Type.h:8038
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isExtVectorType() const
Definition: Type.h:7734
bool isExtVectorBoolType() const
Definition: Type.h:7738
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7908
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2661
bool isFunctionType() const
Definition: Type.h:7620
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
bool isRecordType() const
Definition: Type.h:7718
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1885
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
TypoExpr - Internal placeholder for expressions where typo correction still needs to be performed and...
Definition: Expr.h:6626
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2235
Represents a C++ unqualified-id that has been parsed.
Definition: DeclSpec.h:1025
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent)
Definition: ExprCXX.cpp:372
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3936
static UnresolvedMemberExpr * Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.cpp:1586
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
const DeclAccessPair & getPair() const
Definition: UnresolvedSet.h:54
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:707
QualType getType() const
Definition: Decl.h:718
Represents a variable declaration or definition.
Definition: Decl.h:919
void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation=SourceLocation())
For a static data member that was instantiated from a static data member of a class template,...
Definition: Decl.cpp:2880
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition: Decl.cpp:2760
Declaration of a variable template.
unsigned getNumElements() const
Definition: Type.h:3996
QualType getElementType() const
Definition: Type.h:3995
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
Definition: ScopeInfo.h:1087
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
@ CPlusPlus
Definition: LangStandard.h:55
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:146
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
Definition: Specifiers.h:158
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:148
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
Definition: Specifiers.h:151
@ IK_ConstructorName
A constructor name.
ObjCMethodFamily
A family of Objective-C methods.
ExprResult ExprEmpty()
Definition: Ownership.h:271
ActionResult< Expr * > ExprResult
Definition: Ownership.h:248
ExprResult ExprError()
Definition: Ownership.h:264
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:129
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:132
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:136
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1275
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:191
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.