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