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