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