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