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"
16#include "clang/AST/ExprCXX.h"
17#include "clang/AST/ExprObjC.h"
19#include "clang/Sema/Lookup.h"
20#include "clang/Sema/Overload.h"
21#include "clang/Sema/Scope.h"
24#include "clang/Sema/SemaObjC.h"
26
27using namespace clang;
28using 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
42enum 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
118 }
119
120 // Collect all the declaring classes of instance members we find.
121 bool hasNonInstance = false;
122 bool isField = false;
123 BaseSet Classes;
124 for (NamedDecl *D : R) {
125 // Look through any using decls.
126 D = D->getUnderlyingDecl();
127
128 if (D->isCXXInstanceMember()) {
129 isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
130 isa<IndirectFieldDecl>(D);
131
132 CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
133 Classes.insert(R->getCanonicalDecl());
134 } else
135 hasNonInstance = true;
136 }
137
138 // If we didn't find any instance members, it can't be an implicit
139 // member reference.
140 if (Classes.empty())
141 return IMA_Static;
142
143 if (couldInstantiateToStatic)
144 return IMA_Dependent;
145
146 // C++11 [expr.prim.general]p12:
147 // An id-expression that denotes a non-static data member or non-static
148 // member function of a class can only be used:
149 // (...)
150 // - if that id-expression denotes a non-static data member and it
151 // appears in an unevaluated operand.
152 //
153 // This rule is specific to C++11. However, we also permit this form
154 // in unevaluated inline assembly operands, like the operand to a SIZE.
155 IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false'
156 assert(!AbstractInstanceResult);
157 switch (SemaRef.ExprEvalContexts.back().Context) {
158 case Sema::ExpressionEvaluationContext::Unevaluated:
159 case Sema::ExpressionEvaluationContext::UnevaluatedList:
160 if (isField && SemaRef.getLangOpts().CPlusPlus11)
161 AbstractInstanceResult = IMA_Field_Uneval_Context;
162 break;
163
164 case Sema::ExpressionEvaluationContext::UnevaluatedAbstract:
165 AbstractInstanceResult = IMA_Abstract;
166 break;
167
168 case Sema::ExpressionEvaluationContext::DiscardedStatement:
169 case Sema::ExpressionEvaluationContext::ConstantEvaluated:
170 case Sema::ExpressionEvaluationContext::ImmediateFunctionContext:
171 case Sema::ExpressionEvaluationContext::PotentiallyEvaluated:
172 case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
173 break;
174 }
175
176 // If the current context is not an instance method, it can't be
177 // an implicit member reference.
178 if (isStaticOrExplicitContext) {
179 if (hasNonInstance)
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.
223static 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:
313 case IMA_Unresolved:
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:
334 TemplateKWLoc, R.getLookupNameInfo(), /*RequiresADL=*/false,
335 TemplateArgs, R.begin(), R.end(), /*KnownDependent=*/true);
336
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.
348static bool
349IsRGBA(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.
364static 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.
373static 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
508 const Selector &Sel,
509 ASTContext &Context) {
510 if (Member)
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
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() ||
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,
661 return true;
662}
663
664namespace {
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.
669class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback {
670public:
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
710private:
711 const RecordDecl *const Record;
712};
713
714}
715
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
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(),
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 {
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
929static ExprResult
930BuildMSPropertyRefExpr(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))
965 }
966 }
967
968 return E;
969}
970
971/// Determine if the given scope is within a function-try-block handler.
972static 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.
1098 // Suppress any lookup-related diagnostics; we'll do these when we
1099 // pick a member.
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) {
1198 SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), VarTempl, MemberLoc);
1199 return ExprError();
1200 }
1201
1202 DeclResult VDecl = CheckVarTemplateId(VarTempl, TemplateKWLoc,
1203 MemberNameInfo.getLoc(), *TemplateArgs);
1204 if (VDecl.isInvalid())
1205 return ExprError();
1206
1207 // Non-dependent member, but dependent template arguments.
1208 if (!VDecl.get())
1210 BaseExpr, BaseExpr->getType(), IsArrow, OpLoc, SS, TemplateKWLoc,
1211 FirstQualifierInScope, MemberNameInfo, TemplateArgs);
1212
1213 VarDecl *Var = cast<VarDecl>(VDecl.get());
1216
1217 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1218 SS.getWithLocInContext(Context), TemplateKWLoc, Var,
1219 FoundDecl, /*HadMultipleCandidates=*/false,
1220 MemberNameInfo, Var->getType().getNonReferenceType(),
1221 VK_LValue, OK_Ordinary, TemplateArgs);
1222 }
1223
1224 // We found something that we didn't expect. Complain.
1225 if (isa<TypeDecl>(MemberDecl))
1226 Diag(MemberLoc, diag::err_typecheck_member_reference_type)
1227 << MemberName << BaseType << int(IsArrow);
1228 else
1229 Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
1230 << MemberName << BaseType << int(IsArrow);
1231
1232 Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
1233 << MemberName;
1235 return ExprError();
1236}
1237
1238/// Given that normal member access failed on the given expression,
1239/// and given that the expression's type involves builtin-id or
1240/// builtin-Class, decide whether substituting in the redefinition
1241/// types would be profitable. The redefinition type is whatever
1242/// this translation unit tried to typedef to id/Class; we store
1243/// it to the side and then re-use it in places like this.
1245 const ObjCObjectPointerType *opty
1246 = base.get()->getType()->getAs<ObjCObjectPointerType>();
1247 if (!opty) return false;
1248
1249 const ObjCObjectType *ty = opty->getObjectType();
1250
1251 QualType redef;
1252 if (ty->isObjCId()) {
1254 } else if (ty->isObjCClass()) {
1256 } else {
1257 return false;
1258 }
1259
1260 // Do the substitution as long as the redefinition type isn't just a
1261 // possibly-qualified pointer to builtin-id or builtin-Class again.
1262 opty = redef->getAs<ObjCObjectPointerType>();
1263 if (opty && !opty->getObjectType()->getInterface())
1264 return false;
1265
1266 base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
1267 return true;
1268}
1269
1271 return T->isRecordType();
1272}
1274 if (const PointerType *PT = T->getAs<PointerType>())
1275 return PT->getPointeeType()->isRecordType();
1276 return false;
1277}
1278
1279/// Perform conversions on the LHS of a member access expression.
1282 if (IsArrow && !Base->getType()->isFunctionType())
1284
1285 return CheckPlaceholderExpr(Base);
1286}
1287
1288/// Look up the given member of the given non-type-dependent
1289/// expression. This can return in one of two ways:
1290/// * If it returns a sentinel null-but-valid result, the caller will
1291/// assume that lookup was performed and the results written into
1292/// the provided structure. It will take over from there.
1293/// * Otherwise, the returned expression will be produced in place of
1294/// an ordinary member expression.
1295///
1296/// The ObjCImpDecl bit is a gross hack that will need to be properly
1297/// fixed for ObjC++.
1299 ExprResult &BaseExpr, bool &IsArrow,
1300 SourceLocation OpLoc, CXXScopeSpec &SS,
1301 Decl *ObjCImpDecl, bool HasTemplateArgs,
1302 SourceLocation TemplateKWLoc) {
1303 assert(BaseExpr.get() && "no base expression");
1304
1305 // Perform default conversions.
1306 BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
1307 if (BaseExpr.isInvalid())
1308 return ExprError();
1309
1310 QualType BaseType = BaseExpr.get()->getType();
1311
1312 DeclarationName MemberName = R.getLookupName();
1313 SourceLocation MemberLoc = R.getNameLoc();
1314
1315 // For later type-checking purposes, turn arrow accesses into dot
1316 // accesses. The only access type we support that doesn't follow
1317 // the C equivalence "a->b === (*a).b" is ObjC property accesses,
1318 // and those never use arrows, so this is unaffected.
1319 if (IsArrow) {
1320 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1321 BaseType = Ptr->getPointeeType();
1322 else if (const ObjCObjectPointerType *Ptr =
1323 BaseType->getAs<ObjCObjectPointerType>())
1324 BaseType = Ptr->getPointeeType();
1325 else if (BaseType->isFunctionType())
1326 goto fail;
1327 else if (BaseType->isDependentType())
1328 BaseType = S.Context.DependentTy;
1329 else if (BaseType->isRecordType()) {
1330 // Recover from arrow accesses to records, e.g.:
1331 // struct MyRecord foo;
1332 // foo->bar
1333 // This is actually well-formed in C++ if MyRecord has an
1334 // overloaded operator->, but that should have been dealt with
1335 // by now--or a diagnostic message already issued if a problem
1336 // was encountered while looking for the overloaded operator->.
1337 if (!S.getLangOpts().CPlusPlus) {
1338 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1339 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1340 << FixItHint::CreateReplacement(OpLoc, ".");
1341 }
1342 IsArrow = false;
1343 } else {
1344 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
1345 << BaseType << BaseExpr.get()->getSourceRange();
1346 return ExprError();
1347 }
1348 }
1349
1350 // If the base type is an atomic type, this access is undefined behavior per
1351 // C11 6.5.2.3p5. Instead of giving a typecheck error, we'll warn the user
1352 // about the UB and recover by converting the atomic lvalue into a non-atomic
1353 // lvalue. Because this is inherently unsafe as an atomic operation, the
1354 // warning defaults to an error.
1355 if (const auto *ATy = BaseType->getAs<AtomicType>()) {
1356 S.DiagRuntimeBehavior(OpLoc, nullptr,
1357 S.PDiag(diag::warn_atomic_member_access));
1358 BaseType = ATy->getValueType().getUnqualifiedType();
1359 BaseExpr = ImplicitCastExpr::Create(
1360 S.Context, IsArrow ? S.Context.getPointerType(BaseType) : BaseType,
1361 CK_AtomicToNonAtomic, BaseExpr.get(), nullptr,
1362 BaseExpr.get()->getValueKind(), FPOptionsOverride());
1363 }
1364
1365 // Handle field access to simple records.
1366 if (BaseType->getAsRecordDecl()) {
1367 TypoExpr *TE = nullptr;
1368 if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow,
1369 SS, HasTemplateArgs, TemplateKWLoc, TE))
1370 return ExprError();
1371
1372 // Returning valid-but-null is how we indicate to the caller that
1373 // the lookup result was filled in. If typo correction was attempted and
1374 // failed, the lookup result will have been cleared--that combined with the
1375 // valid-but-null ExprResult will trigger the appropriate diagnostics.
1376 return ExprResult(TE);
1377 } else if (BaseType->isDependentType()) {
1379 return ExprEmpty();
1380 }
1381
1382 // Handle ivar access to Objective-C objects.
1383 if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
1384 if (!SS.isEmpty() && !SS.isInvalid()) {
1385 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1386 << 1 << SS.getScopeRep()
1388 SS.clear();
1389 }
1390
1392
1393 // There are three cases for the base type:
1394 // - builtin id (qualified or unqualified)
1395 // - builtin Class (qualified or unqualified)
1396 // - an interface
1397 ObjCInterfaceDecl *IDecl = OTy->getInterface();
1398 if (!IDecl) {
1399 if (S.getLangOpts().ObjCAutoRefCount &&
1400 (OTy->isObjCId() || OTy->isObjCClass()))
1401 goto fail;
1402 // There's an implicit 'isa' ivar on all objects.
1403 // But we only actually find it this way on objects of type 'id',
1404 // apparently.
1405 if (OTy->isObjCId() && Member->isStr("isa"))
1406 return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1407 OpLoc, S.Context.getObjCClassType());
1408 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1409 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1410 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1411 goto fail;
1412 }
1413
1414 if (S.RequireCompleteType(OpLoc, BaseType,
1415 diag::err_typecheck_incomplete_tag,
1416 BaseExpr.get()))
1417 return ExprError();
1418
1419 ObjCInterfaceDecl *ClassDeclared = nullptr;
1420 ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1421
1422 if (!IV) {
1423 // Attempt to correct for typos in ivar names.
1424 DeclFilterCCC<ObjCIvarDecl> Validator{};
1425 Validator.IsObjCIvarLookup = IsArrow;
1426 if (TypoCorrection Corrected = S.CorrectTypo(
1427 R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
1428 Validator, Sema::CTK_ErrorRecovery, IDecl)) {
1429 IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
1430 S.diagnoseTypo(
1431 Corrected,
1432 S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1433 << IDecl->getDeclName() << MemberName);
1434
1435 // Figure out the class that declares the ivar.
1436 assert(!ClassDeclared);
1437
1438 Decl *D = cast<Decl>(IV->getDeclContext());
1439 if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1440 D = Category->getClassInterface();
1441
1442 if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1443 ClassDeclared = Implementation->getClassInterface();
1444 else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1445 ClassDeclared = Interface;
1446
1447 assert(ClassDeclared && "cannot query interface");
1448 } else {
1449 if (IsArrow &&
1452 S.Diag(MemberLoc, diag::err_property_found_suggest)
1453 << Member << BaseExpr.get()->getType()
1454 << FixItHint::CreateReplacement(OpLoc, ".");
1455 return ExprError();
1456 }
1457
1458 S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1459 << IDecl->getDeclName() << MemberName
1460 << BaseExpr.get()->getSourceRange();
1461 return ExprError();
1462 }
1463 }
1464
1465 assert(ClassDeclared);
1466
1467 // If the decl being referenced had an error, return an error for this
1468 // sub-expr without emitting another error, in order to avoid cascading
1469 // error cases.
1470 if (IV->isInvalidDecl())
1471 return ExprError();
1472
1473 // Check whether we can reference this field.
1474 if (S.DiagnoseUseOfDecl(IV, MemberLoc))
1475 return ExprError();
1478 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1479 if (ObjCMethodDecl *MD = S.getCurMethodDecl())
1480 ClassOfMethodDecl = MD->getClassInterface();
1481 else if (ObjCImpDecl && S.getCurFunctionDecl()) {
1482 // Case of a c-function declared inside an objc implementation.
1483 // FIXME: For a c-style function nested inside an objc implementation
1484 // class, there is no implementation context available, so we pass
1485 // down the context as argument to this routine. Ideally, this context
1486 // need be passed down in the AST node and somehow calculated from the
1487 // AST for a function decl.
1488 if (ObjCImplementationDecl *IMPD =
1489 dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1490 ClassOfMethodDecl = IMPD->getClassInterface();
1491 else if (ObjCCategoryImplDecl* CatImplClass =
1492 dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1493 ClassOfMethodDecl = CatImplClass->getClassInterface();
1494 }
1495 if (!S.getLangOpts().DebuggerSupport) {
1497 if (!declaresSameEntity(ClassDeclared, IDecl) ||
1498 !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
1499 S.Diag(MemberLoc, diag::err_private_ivar_access)
1500 << IV->getDeclName();
1501 } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1502 // @protected
1503 S.Diag(MemberLoc, diag::err_protected_ivar_access)
1504 << IV->getDeclName();
1505 }
1506 }
1507 bool warn = true;
1508 if (S.getLangOpts().ObjCWeak) {
1509 Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1510 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1511 if (UO->getOpcode() == UO_Deref)
1512 BaseExp = UO->getSubExpr()->IgnoreParenCasts();
1513
1514 if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
1515 if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1516 S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
1517 warn = false;
1518 }
1519 }
1520 if (warn) {
1521 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
1522 ObjCMethodFamily MF = MD->getMethodFamily();
1523 warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
1524 !S.ObjC().IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
1525 }
1526 if (warn)
1527 S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
1528 }
1529
1531 IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1532 IsArrow);
1533
1535 if (!S.isUnevaluatedContext() &&
1536 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1538 }
1539
1540 return Result;
1541 }
1542
1543 // Objective-C property access.
1544 const ObjCObjectPointerType *OPT;
1545 if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
1546 if (!SS.isEmpty() && !SS.isInvalid()) {
1547 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1548 << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
1549 SS.clear();
1550 }
1551
1552 // This actually uses the base as an r-value.
1553 BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
1554 if (BaseExpr.isInvalid())
1555 return ExprError();
1556
1557 assert(S.Context.hasSameUnqualifiedType(BaseType,
1558 BaseExpr.get()->getType()));
1559
1561
1562 const ObjCObjectType *OT = OPT->getObjectType();
1563
1564 // id, with and without qualifiers.
1565 if (OT->isObjCId()) {
1566 // Check protocols on qualified interfaces.
1568 if (Decl *PMDecl =
1569 FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
1570 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1571 // Check the use of this declaration
1572 if (S.DiagnoseUseOfDecl(PD, MemberLoc))
1573 return ExprError();
1574
1575 return new (S.Context)
1577 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1578 }
1579
1580 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
1581 Selector SetterSel =
1583 S.PP.getSelectorTable(),
1584 Member);
1585 ObjCMethodDecl *SMD = nullptr;
1586 if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
1587 /*Property id*/ nullptr,
1588 SetterSel, S.Context))
1589 SMD = dyn_cast<ObjCMethodDecl>(SDecl);
1590
1591 return new (S.Context)
1593 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1594 }
1595 }
1596 // Use of id.member can only be for a property reference. Do not
1597 // use the 'id' redefinition in this case.
1598 if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1599 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1600 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1601
1602 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1603 << MemberName << BaseType);
1604 }
1605
1606 // 'Class', unqualified only.
1607 if (OT->isObjCClass()) {
1608 // Only works in a method declaration (??!).
1610 if (!MD) {
1611 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1612 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1613 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1614
1615 goto fail;
1616 }
1617
1618 // Also must look for a getter name which uses property syntax.
1620 ObjCInterfaceDecl *IFace = MD->getClassInterface();
1621 if (!IFace)
1622 goto fail;
1623
1624 ObjCMethodDecl *Getter;
1625 if ((Getter = IFace->lookupClassMethod(Sel))) {
1626 // Check the use of this method.
1627 if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
1628 return ExprError();
1629 } else
1630 Getter = IFace->lookupPrivateMethod(Sel, false);
1631 // If we found a getter then this may be a valid dot-reference, we
1632 // will look for the matching setter, in case it is needed.
1633 Selector SetterSel =
1635 S.PP.getSelectorTable(),
1636 Member);
1637 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1638 if (!Setter) {
1639 // If this reference is in an @implementation, also check for 'private'
1640 // methods.
1641 Setter = IFace->lookupPrivateMethod(SetterSel, false);
1642 }
1643
1644 if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
1645 return ExprError();
1646
1647 if (Getter || Setter) {
1648 return new (S.Context) ObjCPropertyRefExpr(
1649 Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1650 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1651 }
1652
1653 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1654 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1655 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1656
1657 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1658 << MemberName << BaseType);
1659 }
1660
1661 // Normal property access.
1663 OPT, BaseExpr.get(), OpLoc, MemberName, MemberLoc, SourceLocation(),
1664 QualType(), false);
1665 }
1666
1667 if (BaseType->isExtVectorBoolType()) {
1668 // We disallow element access for ext_vector_type bool. There is no way to
1669 // materialize a reference to a vector element as a pointer (each element is
1670 // one bit in the vector).
1671 S.Diag(R.getNameLoc(), diag::err_ext_vector_component_name_illegal)
1672 << MemberName
1673 << (BaseExpr.get() ? BaseExpr.get()->getSourceRange() : SourceRange());
1674 return ExprError();
1675 }
1676
1677 // Handle 'field access' to vectors, such as 'V.xx'.
1678 if (BaseType->isExtVectorType()) {
1679 // FIXME: this expr should store IsArrow.
1681 ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
1682 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
1683 Member, MemberLoc);
1684 if (ret.isNull())
1685 return ExprError();
1686 Qualifiers BaseQ =
1688 ret = S.Context.getQualifiedType(ret, BaseQ);
1689
1690 return new (S.Context)
1691 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
1692 }
1693
1694 // Adjust builtin-sel to the appropriate redefinition type if that's
1695 // not just a pointer to builtin-sel again.
1696 if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
1698 BaseExpr = S.ImpCastExprToType(
1699 BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1700 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1701 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1702 }
1703
1704 // Failure cases.
1705 fail:
1706
1707 // Recover from dot accesses to pointers, e.g.:
1708 // type *foo;
1709 // foo.bar
1710 // This is actually well-formed in two cases:
1711 // - 'type' is an Objective C type
1712 // - 'bar' is a pseudo-destructor name which happens to refer to
1713 // the appropriate pointer type
1714 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1715 if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
1717 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1718 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1719 << FixItHint::CreateReplacement(OpLoc, "->");
1720
1721 if (S.isSFINAEContext())
1722 return ExprError();
1723
1724 // Recurse as an -> access.
1725 IsArrow = true;
1726 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1727 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1728 }
1729 }
1730
1731 // If the user is trying to apply -> or . to a function name, it's probably
1732 // because they forgot parentheses to call that function.
1734 BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1735 /*complain*/ false,
1736 IsArrow ? &isPointerToRecordType : &isRecordType)) {
1737 if (BaseExpr.isInvalid())
1738 return ExprError();
1739 BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1740 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1741 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1742 }
1743
1744 // HLSL supports implicit conversion of scalar types to single element vector
1745 // rvalues in member expressions.
1746 if (S.getLangOpts().HLSL && BaseType->isScalarType()) {
1747 QualType VectorTy = S.Context.getExtVectorType(BaseType, 1);
1748 BaseExpr = S.ImpCastExprToType(BaseExpr.get(), VectorTy, CK_VectorSplat,
1749 BaseExpr.get()->getValueKind());
1750 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, ObjCImpDecl,
1751 HasTemplateArgs, TemplateKWLoc);
1752 }
1753
1754 S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
1755 << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
1756
1757 return ExprError();
1758}
1759
1760/// The main callback when the parser finds something like
1761/// expression . [nested-name-specifier] identifier
1762/// expression -> [nested-name-specifier] identifier
1763/// where 'identifier' encompasses a fairly broad spectrum of
1764/// possibilities, including destructor and operator references.
1765///
1766/// \param OpKind either tok::arrow or tok::period
1767/// \param ObjCImpDecl the current Objective-C \@implementation
1768/// decl; this is an ugly hack around the fact that Objective-C
1769/// \@implementations aren't properly put in the context chain
1771 SourceLocation OpLoc,
1772 tok::TokenKind OpKind,
1773 CXXScopeSpec &SS,
1774 SourceLocation TemplateKWLoc,
1776 Decl *ObjCImpDecl) {
1777 if (SS.isSet() && SS.isInvalid())
1778 return ExprError();
1779
1780 // Warn about the explicit constructor calls Microsoft extension.
1781 if (getLangOpts().MicrosoftExt &&
1783 Diag(Id.getSourceRange().getBegin(),
1784 diag::ext_ms_explicit_constructor_call);
1785
1786 TemplateArgumentListInfo TemplateArgsBuffer;
1787
1788 // Decompose the name into its component parts.
1789 DeclarationNameInfo NameInfo;
1790 const TemplateArgumentListInfo *TemplateArgs;
1791 DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1792 NameInfo, TemplateArgs);
1793
1794 bool IsArrow = (OpKind == tok::arrow);
1795
1796 if (getLangOpts().HLSL && IsArrow)
1797 return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 2);
1798
1799 NamedDecl *FirstQualifierInScope
1800 = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
1801
1802 // This is a postfix expression, so get rid of ParenListExprs.
1804 if (Result.isInvalid()) return ExprError();
1805 Base = Result.get();
1806
1807 ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
1809 Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc,
1810 FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs);
1811
1812 if (!Res.isInvalid() && isa<MemberExpr>(Res.get()))
1813 CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get()));
1814
1815 return Res;
1816}
1817
1818void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
1820 return;
1821
1822 QualType ResultTy = E->getType();
1823
1824 // Member accesses have four cases:
1825 // 1: non-array member via "->": dereferences
1826 // 2: non-array member via ".": nothing interesting happens
1827 // 3: array member access via "->": nothing interesting happens
1828 // (this returns an array lvalue and does not actually dereference memory)
1829 // 4: array member access via ".": *adds* a layer of indirection
1830 if (ResultTy->isArrayType()) {
1831 if (!E->isArrow()) {
1832 // This might be something like:
1833 // (*structPtr).arrayMember
1834 // which behaves roughly like:
1835 // &(*structPtr).pointerMember
1836 // in that the apparent dereference in the base expression does not
1837 // actually happen.
1838 CheckAddressOfNoDeref(E->getBase());
1839 }
1840 } else if (E->isArrow()) {
1841 if (const auto *Ptr = dyn_cast<PointerType>(
1843 if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
1844 ExprEvalContexts.back().PossibleDerefs.insert(E);
1845 }
1846 }
1847}
1848
1850Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1851 SourceLocation OpLoc, const CXXScopeSpec &SS,
1852 FieldDecl *Field, DeclAccessPair FoundDecl,
1853 const DeclarationNameInfo &MemberNameInfo) {
1854 // x.a is an l-value if 'a' has a reference type. Otherwise:
1855 // x.a is an l-value/x-value/pr-value if the base is (and note
1856 // that *x is always an l-value), except that if the base isn't
1857 // an ordinary object then we must have an rvalue.
1860 if (!IsArrow) {
1861 if (BaseExpr->getObjectKind() == OK_Ordinary)
1862 VK = BaseExpr->getValueKind();
1863 else
1864 VK = VK_PRValue;
1865 }
1866 if (VK != VK_PRValue && Field->isBitField())
1867 OK = OK_BitField;
1868
1869 // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1870 QualType MemberType = Field->getType();
1871 if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1872 MemberType = Ref->getPointeeType();
1873 VK = VK_LValue;
1874 } else {
1875 QualType BaseType = BaseExpr->getType();
1876 if (IsArrow) BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1877
1878 Qualifiers BaseQuals = BaseType.getQualifiers();
1879
1880 // GC attributes are never picked up by members.
1881 BaseQuals.removeObjCGCAttr();
1882
1883 // CVR attributes from the base are picked up by members,
1884 // except that 'mutable' members don't pick up 'const'.
1885 if (Field->isMutable()) BaseQuals.removeConst();
1886
1887 Qualifiers MemberQuals =
1889
1890 assert(!MemberQuals.hasAddressSpace());
1891
1892 Qualifiers Combined = BaseQuals + MemberQuals;
1893 if (Combined != MemberQuals)
1894 MemberType = Context.getQualifiedType(MemberType, Combined);
1895
1896 // Pick up NoDeref from the base in case we end up using AddrOf on the
1897 // result. E.g. the expression
1898 // &someNoDerefPtr->pointerMember
1899 // should be a noderef pointer again.
1900 if (BaseType->hasAttr(attr::NoDeref))
1901 MemberType =
1902 Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
1903 }
1904
1905 auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
1906 if (!(CurMethod && CurMethod->isDefaulted()))
1907 UnusedPrivateFields.remove(Field);
1908
1910 FoundDecl, Field);
1911 if (Base.isInvalid())
1912 return ExprError();
1913
1914 // Build a reference to a private copy for non-static data members in
1915 // non-static member functions, privatized by OpenMP constructs.
1916 if (getLangOpts().OpenMP && IsArrow &&
1918 isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
1919 if (auto *PrivateCopy = OpenMP().isOpenMPCapturedDecl(Field)) {
1920 return OpenMP().getOpenMPCapturedExpr(PrivateCopy, VK, OK,
1921 MemberNameInfo.getLoc());
1922 }
1923 }
1924
1925 return BuildMemberExpr(
1926 Base.get(), IsArrow, OpLoc, SS.getWithLocInContext(Context),
1927 /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1928 /*HadMultipleCandidates=*/false, MemberNameInfo, MemberType, VK, OK);
1929}
1930
1931/// Builds an implicit member access expression. The current context
1932/// is known to be an instance method, and the given unqualified lookup
1933/// set is known to contain only instance members, at least one of which
1934/// is from an appropriate type.
1937 SourceLocation TemplateKWLoc,
1938 LookupResult &R,
1939 const TemplateArgumentListInfo *TemplateArgs,
1940 bool IsKnownInstance, const Scope *S) {
1941 assert(!R.empty() && !R.isAmbiguous());
1942
1943 SourceLocation loc = R.getNameLoc();
1944
1945 // If this is known to be an instance access, go ahead and build an
1946 // implicit 'this' expression now.
1947 QualType ThisTy = getCurrentThisType();
1948 assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
1949
1950 Expr *baseExpr = nullptr; // null signifies implicit access
1951 if (IsKnownInstance) {
1953 if (SS.getRange().isValid())
1954 Loc = SS.getRange().getBegin();
1955 baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
1956 }
1957
1959 baseExpr, ThisTy,
1960 /*OpLoc=*/SourceLocation(),
1961 /*IsArrow=*/!getLangOpts().HLSL, SS, TemplateKWLoc,
1962 /*FirstQualifierInScope=*/nullptr, R, TemplateArgs, S);
1963}
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
uint32_t Id
Definition: SemaARM.cpp:1140
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)
static Decl * FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl *PDecl, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
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 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 Decl * FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
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 bool IsInFnTryBlockHandler(const Scope *S)
Determine if the given scope is within a function-try-block handler.
SourceRange Range
Definition: SemaObjC.cpp:757
SourceLocation Loc
Definition: SemaObjC.cpp:758
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static std::optional< QualType > getPointeeType(const MemRegion *R)
__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:2104
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2593
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:1909
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:2175
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2636
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:1896
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:1883
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:1531
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
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
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:95
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:1435
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2065
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition: DeclBase.h:2194
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1313
bool isRecord() const
Definition: DeclBase.h:2145
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1383
DeclContext * getNonTransparentContext()
Definition: DeclBase.cpp:1394
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
DeclContext * getDeclContext()
Definition: DeclBase.h:454
AccessSpecifier getAccess() const
Definition: DeclBase.h:513
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
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.
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:916
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3299
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:3064
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:3059
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:3039
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:6113
ExtVectorType - Extended vector type.
Definition: Type.h:4080
bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const
Definition: Type.h:4133
static int getNumericAccessorIdx(char c)
Definition: Type.h:4098
static int getPointAccessorIdx(char c)
Definition: Type.h:4088
Represents difference between two FPOptions values.
Definition: LangOptions.h:915
Represents a member of a struct/union/class.
Definition: Decl.h:3059
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:134
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition: Diagnostic.h:123
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:97
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2708
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4675
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:2074
Represents a field injected from an anonymous union/struct into the parent scope.
Definition: Decl.h:3343
chain_iterator chain_end() const
Definition: Decl.h:3369
chain_iterator chain_begin() const
Definition: Decl.h:3368
VarDecl * getVarDecl() const
Definition: Decl.h:3378
ArrayRef< NamedDecl * >::const_iterator chain_iterator
Definition: Decl.h:3363
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
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
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
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:568
bool isAmbiguous() const
Definition: Lookup.h:324
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:331
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
Definition: Lookup.h:452
Sema::LookupNameKind getLookupKind() const
Gets the kind of lookup to perform.
Definition: Lookup.h:275
Sema & getSema() const
Get the Sema object that this lookup result is searching with.
Definition: Lookup.h:670
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:575
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:933
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3172
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:3382
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:1754
Expr * getBase() const
Definition: Expr.h:3249
bool isArrow() const
Definition: Expr.h:3356
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition: Decl.cpp:1952
bool isCXXClassMember() const
Determine whether this declaration is a C++ class member.
Definition: Decl.h:372
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
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
Definition: DeclObjC.h:1850
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition: DeclObjC.cpp:637
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:7024
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Definition: Type.h:7061
qual_range quals() const
Definition: Type.h:7143
Represents a class type in Objective C.
Definition: Type.h:6770
bool isObjCClass() const
Definition: Type.h:6838
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Definition: Type.h:7003
bool isObjCId() const
Definition: Type.h:6834
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:3158
QualType getPointeeType() const
Definition: Type.h:3168
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:1305
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:7415
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition: Type.h:1446
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:7576
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:4170
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5568
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3399
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:60
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaBase.cpp:32
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:9512
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition: Sema.h:9542
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:478
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:713
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:7406
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:7418
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:2354
SemaOpenMP & OpenMP()
Definition: Sema.h:1090
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:3661
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:873
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:7946
SemaObjC & ObjC()
Definition: Sema.h:1075
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:2688
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:765
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:689
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition: Sema.cpp:1552
const LangOptions & getLangOpts() const
Definition: Sema.h:535
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:2257
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:872
bool isPotentialImplicitMemberAccess(const CXXScopeSpec &SS, LookupResult &R, bool IsAddressOfOperand)
Check whether an expression might be an implicit class member access.
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
Definition: SemaInit.cpp:8575
NamedDeclSetType UnusedPrivateFields
Set containing all declared private fields that are not used.
Definition: Sema.h:4855
SemaHLSL & HLSL()
Definition: Sema.h:1040
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:904
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:653
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
Definition: SemaExpr.cpp:3233
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:1008
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
Definition: Sema.h:6331
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:20821
QualType CXXThisTypeOverride
When non-NULL, the C++ 'this' expression is allowed despite the current context not being a non-stati...
Definition: Sema.h:6593
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:20099
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExternalSemaSource * getExternalSource() const
Definition: Sema.h:545
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
@ CTK_ErrorRecovery
Definition: Sema.h:7650
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:8835
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
Definition: Sema.h:6481
bool isDependentScopeSpecifier(const CXXScopeSpec &SS)
DiagnosticsEngine & Diags
Definition: Sema.h:875
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition: SemaExpr.cpp:529
void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc)
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:19875
ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member)
Cast a base object to a member's actual type.
Definition: SemaExpr.cpp:3013
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
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:7694
bool isPointerType() const
Definition: Type.h:7628
bool isObjCSelType() const
Definition: Type.h:7809
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8213
bool isScalarType() const
Definition: Type.h:8024
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:7738
bool isExtVectorBoolType() const
Definition: Type.h:7742
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7894
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2669
bool isFunctionType() const
Definition: Type.h:7624
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8146
bool isRecordType() const
Definition: Type.h:7722
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:6585
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2183
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:419
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3941
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:1633
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
const DeclAccessPair & getPair() const
Definition: UnresolvedSet.h:55
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
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:2872
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:2752
Declaration of a variable template.
unsigned getNumElements() const
Definition: Type.h:4003
QualType getElementType() const
Definition: Type.h:4002
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
@ Result
The result type of a method or function.
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:1274
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:191
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" 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.