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