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