clang 23.0.0git
SemaExprMember.cpp
Go to the documentation of this file.
1//===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis member access expressions.
10//
11//===----------------------------------------------------------------------===//
12#include "clang/AST/DeclCXX.h"
13#include "clang/AST/DeclObjC.h"
15#include "clang/AST/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 HasRepeated = false;
398 bool HasIndex[16] = {};
399
400 int Idx;
401
402 // Check that we've found one of the special components, or that the component
403 // names must come from the same set.
404 if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
405 !strcmp(compStr, "even") || !strcmp(compStr, "odd")) {
406 HalvingSwizzle = true;
407 } else if (!HexSwizzle &&
408 (Idx = vecType->getPointAccessorIdx(*compStr)) != -1) {
409 bool HasRGBA = IsRGBA(*compStr);
410 do {
411 // Ensure that xyzw and rgba components don't intermingle.
412 if (HasRGBA != IsRGBA(*compStr))
413 break;
414 if (HasIndex[Idx]) HasRepeated = true;
415 HasIndex[Idx] = true;
416 compStr++;
417 } while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1);
418
419 // Emit a warning if an rgba selector is used earlier than OpenCL C 3.0.
420 if (HasRGBA || (*compStr && IsRGBA(*compStr))) {
421 if (S.getLangOpts().OpenCL &&
423 const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr;
424 S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector)
425 << StringRef(DiagBegin, 1) << SourceRange(CompLoc);
426 }
427 }
428 } else {
429 if (HexSwizzle) compStr++;
430 while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) {
431 if (HasIndex[Idx]) HasRepeated = true;
432 HasIndex[Idx] = true;
433 compStr++;
434 }
435 }
436
437 if (!HalvingSwizzle && *compStr) {
438 // We didn't get to the end of the string. This means the component names
439 // didn't come from the same set *or* we encountered an illegal name.
440 size_t Offset = compStr - CompName->getNameStart() + 1;
441 char Fmt[3] = {'\'', *compStr, '\''};
442 S.Diag(OpLoc.getLocWithOffset(Offset),
443 diag::err_ext_vector_component_name_illegal)
444 << StringRef(Fmt, 3) << SourceRange(CompLoc);
445 return QualType();
446 }
447
448 // Ensure no component accessor exceeds the width of the vector type it
449 // operates on.
450 if (!HalvingSwizzle) {
451 compStr = CompName->getNameStart();
452
453 if (HexSwizzle)
454 compStr++;
455
456 while (*compStr) {
457 if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) {
458 S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
459 << baseType << SourceRange(CompLoc);
460 return QualType();
461 }
462 }
463 }
464
465 // OpenCL mode requires swizzle length to be in accordance with accepted
466 // sizes. Clang however supports arbitrary lengths for other languages.
467 if (S.getLangOpts().OpenCL && !HalvingSwizzle) {
468 unsigned SwizzleLength = CompName->getLength();
469
470 if (HexSwizzle)
471 SwizzleLength--;
472
473 if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) {
474 S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length)
475 << SwizzleLength << SourceRange(CompLoc);
476 return QualType();
477 }
478 }
479
480 // The component accessor looks fine - now we need to compute the actual type.
481 // The vector type is implied by the component accessor. For example,
482 // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
483 // vec4.s0 is a float, vec4.s23 is a vec3, etc.
484 // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
485 unsigned CompSize = HalvingSwizzle ? (vecType->getNumElements() + 1) / 2
486 : CompName->getLength();
487 if (HexSwizzle)
488 CompSize--;
489
490 if (CompSize == 1)
491 return vecType->getElementType();
492
493 if (HasRepeated)
494 VK = VK_PRValue;
495
496 QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize);
497 // Now look up the TypeDefDecl from the vector type. Without this,
498 // diagnostics look bad. We want extended vector types to appear built-in.
499 for (Sema::ExtVectorDeclsType::iterator
501 E = S.ExtVectorDecls.end();
502 I != E; ++I) {
503 if ((*I)->getUnderlyingType() == VT)
505 /*Qualifier=*/std::nullopt, *I);
506 }
507
508 return VT; // should never get here (a typedef type should always be found).
509}
510
513 const Selector &Sel,
514 ASTContext &Context) {
515 if (Member)
518 return PD;
519 if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
520 return OMD;
521
522 for (const auto *I : PDecl->protocols()) {
524 Context))
525 return D;
526 }
527 return nullptr;
528}
529
532 const Selector &Sel,
533 ASTContext &Context) {
534 // Check protocols on qualified interfaces.
535 Decl *GDecl = nullptr;
536 for (const auto *I : QIdTy->quals()) {
537 if (Member)
538 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
540 GDecl = PD;
541 break;
542 }
543 // Also must look for a getter or setter name which uses property syntax.
544 if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) {
545 GDecl = OMD;
546 break;
547 }
548 }
549 if (!GDecl) {
550 for (const auto *I : QIdTy->quals()) {
551 // Search in the protocol-qualifier list of current protocol.
552 GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context);
553 if (GDecl)
554 return GDecl;
555 }
556 }
557 return GDecl;
558}
559
562 bool IsArrow, SourceLocation OpLoc,
563 const CXXScopeSpec &SS,
564 SourceLocation TemplateKWLoc,
565 NamedDecl *FirstQualifierInScope,
566 const DeclarationNameInfo &NameInfo,
567 const TemplateArgumentListInfo *TemplateArgs) {
568 // Even in dependent contexts, try to diagnose base expressions with
569 // obviously wrong types, e.g.:
570 //
571 // T* t;
572 // t.f;
573 //
574 // In Obj-C++, however, the above expression is valid, since it could be
575 // accessing the 'f' property if T is an Obj-C interface. The extra check
576 // allows this, while still reporting an error if T is a struct pointer.
577 if (!IsArrow) {
578 const PointerType *PT = BaseType->getAs<PointerType>();
579 if (PT && (!getLangOpts().ObjC ||
580 PT->getPointeeType()->isRecordType())) {
581 assert(BaseExpr && "cannot happen with implicit member accesses");
582 Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
583 << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange();
584 return ExprError();
585 }
586 }
587
588 assert(BaseType->isDependentType() || NameInfo.getName().isDependentName() ||
590 (TemplateArgs && llvm::any_of(TemplateArgs->arguments(),
591 [](const TemplateArgumentLoc &Arg) {
592 return Arg.getArgument().isDependent();
593 })));
594
595 // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
596 // must have pointer type, and the accessed type is the pointee.
598 Context, BaseExpr, BaseType, IsArrow, OpLoc,
599 SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
600 NameInfo, TemplateArgs);
601}
602
603/// We know that the given qualified member reference points only to
604/// declarations which do not belong to the static type of the base
605/// expression. Diagnose the problem.
607 Expr *BaseExpr,
608 QualType BaseType,
609 const CXXScopeSpec &SS,
610 NamedDecl *rep,
611 const DeclarationNameInfo &nameInfo) {
612 // If this is an implicit member access, use a different set of
613 // diagnostics.
614 if (!BaseExpr)
615 return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo);
616
617 SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated)
618 << SS.getRange() << rep << BaseType;
619}
620
622 QualType BaseType,
623 const CXXScopeSpec &SS,
624 const LookupResult &R) {
625 CXXRecordDecl *BaseRecord =
626 cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType));
627 if (!BaseRecord) {
628 // We can't check this yet because the base type is still
629 // dependent.
630 assert(BaseType->isDependentType());
631 return false;
632 }
633
634 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
635 // If this is an implicit member reference and we find a
636 // non-instance member, it's not an error.
637 if (!BaseExpr && !(*I)->isCXXInstanceMember())
638 return false;
639
640 // Note that we use the DC of the decl, not the underlying decl.
641 DeclContext *DC = (*I)->getDeclContext()->getNonTransparentContext();
642 if (!DC->isRecord())
643 continue;
644
645 CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
646 if (BaseRecord->getCanonicalDecl() == MemberRecord ||
647 !BaseRecord->isProvablyNotDerivedFrom(MemberRecord))
648 return false;
649 }
650
651 DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS,
652 R.getRepresentativeDecl(),
653 R.getLookupNameInfo());
654 return true;
655}
656
658 Expr *BaseExpr, QualType RTy,
659 SourceLocation OpLoc, bool IsArrow,
660 CXXScopeSpec &SS, bool HasTemplateArgs,
661 SourceLocation TemplateKWLoc) {
662 SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
663 if (!RTy->isDependentType() &&
664 !SemaRef.isThisOutsideMemberFunctionBody(RTy) &&
665 SemaRef.RequireCompleteType(
666 OpLoc, RTy, diag::err_typecheck_incomplete_tag, BaseRange))
667 return true;
668
669 // LookupTemplateName/LookupParsedName don't expect these both to exist
670 // simultaneously.
671 QualType ObjectType = SS.isSet() ? QualType() : RTy;
672 if (HasTemplateArgs || TemplateKWLoc.isValid())
673 return SemaRef.LookupTemplateName(R,
674 /*S=*/nullptr, SS, ObjectType,
675 /*EnteringContext=*/false, TemplateKWLoc);
676
677 SemaRef.LookupParsedName(R, /*S=*/nullptr, &SS, ObjectType);
678 return false;
679}
680
682 ExprResult &BaseExpr, bool &IsArrow,
683 SourceLocation OpLoc, CXXScopeSpec &SS,
684 Decl *ObjCImpDecl, bool HasTemplateArgs,
685 SourceLocation TemplateKWLoc);
686
688 Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
689 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
690 NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
691 const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
692 ActOnMemberAccessExtraArgs *ExtraArgs) {
693 LookupResult R(*this, NameInfo, LookupMemberName);
694
695 // Implicit member accesses.
696 if (!Base) {
697 QualType RecordTy = BaseType;
698 if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType();
699 if (LookupMemberExprInRecord(*this, R, nullptr, RecordTy, OpLoc, IsArrow,
700 SS, TemplateArgs != nullptr, TemplateKWLoc))
701 return ExprError();
702
703 // Explicit member accesses.
704 } else {
707 LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS,
708 ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
709 TemplateArgs != nullptr, TemplateKWLoc);
710
711 if (BaseResult.isInvalid())
712 return ExprError();
713 Base = BaseResult.get();
714
715 if (Result.isInvalid())
716 return ExprError();
717
718 if (Result.get())
719 return Result;
720
721 // LookupMemberExpr can modify Base, and thus change BaseType
722 BaseType = Base->getType();
723 }
724
725 // BuildMemberReferenceExpr expects the nested-name-specifier, if any, to be
726 // valid.
727 if (SS.isInvalid())
728 return ExprError();
729
730 return BuildMemberReferenceExpr(Base, BaseType,
731 OpLoc, IsArrow, SS, TemplateKWLoc,
732 FirstQualifierInScope, R, TemplateArgs, S,
733 false, ExtraArgs);
734}
735
738 SourceLocation loc,
739 IndirectFieldDecl *indirectField,
740 DeclAccessPair foundDecl,
741 Expr *baseObjectExpr,
742 SourceLocation opLoc) {
743 // First, build the expression that refers to the base object.
744
745 // Case 1: the base of the indirect field is not a field.
746 VarDecl *baseVariable = indirectField->getVarDecl();
747 CXXScopeSpec EmptySS;
748 if (baseVariable) {
749 assert(baseVariable->getType()->isRecordType());
750
751 // In principle we could have a member access expression that
752 // accesses an anonymous struct/union that's a static member of
753 // the base object's class. However, under the current standard,
754 // static data members cannot be anonymous structs or unions.
755 // Supporting this is as easy as building a MemberExpr here.
756 assert(!baseObjectExpr && "anonymous struct/union is static data member?");
757
758 DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
759
760 ExprResult result
761 = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
762 if (result.isInvalid()) return ExprError();
763
764 baseObjectExpr = result.get();
765 }
766
767 assert((baseVariable || baseObjectExpr) &&
768 "referencing anonymous struct/union without a base variable or "
769 "expression");
770
771 // Build the implicit member references to the field of the
772 // anonymous struct/union.
773 Expr *result = baseObjectExpr;
775 FI = indirectField->chain_begin(), FEnd = indirectField->chain_end();
776
777 // Case 2: the base of the indirect field is a field and the user
778 // wrote a member expression.
779 if (!baseVariable) {
780 FieldDecl *field = cast<FieldDecl>(*FI);
781
782 bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType();
783
784 // Make a nameInfo that properly uses the anonymous name.
785 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
786
787 // Build the first member access in the chain with full information.
788 result =
789 BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(),
790 SS, field, foundDecl, memberNameInfo)
791 .get();
792 if (!result)
793 return ExprError();
794 }
795
796 // In all cases, we should now skip the first declaration in the chain.
797 ++FI;
798
799 while (FI != FEnd) {
800 FieldDecl *field = cast<FieldDecl>(*FI++);
801
802 // FIXME: these are somewhat meaningless
803 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
804 DeclAccessPair fakeFoundDecl =
805 DeclAccessPair::make(field, field->getAccess());
806
807 result =
808 BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(),
809 (FI == FEnd ? SS : EmptySS), field,
810 fakeFoundDecl, memberNameInfo)
811 .get();
812 }
813
814 return result;
815}
816
817static ExprResult
818BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
819 const CXXScopeSpec &SS,
820 MSPropertyDecl *PD,
821 const DeclarationNameInfo &NameInfo) {
822 // Property names are always simple identifiers and therefore never
823 // require any interesting additional storage.
824 return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
827 NameInfo.getLoc());
828}
829
831 Expr *Base, bool IsArrow, SourceLocation OpLoc, NestedNameSpecifierLoc NNS,
832 SourceLocation TemplateKWLoc, ValueDecl *Member, DeclAccessPair FoundDecl,
833 bool HadMultipleCandidates, const DeclarationNameInfo &MemberNameInfo,
835 const TemplateArgumentListInfo *TemplateArgs) {
836 assert((!IsArrow || Base->isPRValue()) &&
837 "-> base must be a pointer prvalue");
838 MemberExpr *E =
839 MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc,
840 Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty,
842 E->setHadMultipleCandidates(HadMultipleCandidates);
844
845 // C++ [except.spec]p17:
846 // An exception-specification is considered to be needed when:
847 // - in an expression the function is the unique lookup result or the
848 // selected member of a set of overloaded functions
849 if (auto *FPT = Ty->getAs<FunctionProtoType>()) {
850 if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
851 if (auto *NewFPT = ResolveExceptionSpec(MemberNameInfo.getLoc(), FPT))
852 E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers()));
853 }
854 }
855
856 return E;
857}
858
859/// Determine if the given scope is within a function-try-block handler.
860static bool IsInFnTryBlockHandler(const Scope *S) {
861 // Walk the scope stack until finding a FnTryCatchScope, or leave the
862 // function scope. If a FnTryCatchScope is found, check whether the TryScope
863 // flag is set. If it is not, it's a function-try-block handler.
864 for (; S != S->getFnParent(); S = S->getParent()) {
865 if (S->isFnTryCatchScope())
866 return (S->getFlags() & Scope::TryScope) != Scope::TryScope;
867 }
868 return false;
869}
870
873 SourceLocation OpLoc, bool IsArrow,
874 const CXXScopeSpec &SS,
875 SourceLocation TemplateKWLoc,
876 NamedDecl *FirstQualifierInScope,
877 LookupResult &R,
878 const TemplateArgumentListInfo *TemplateArgs,
879 const Scope *S,
880 bool SuppressQualifierCheck,
881 ActOnMemberAccessExtraArgs *ExtraArgs) {
882 assert(!SS.isInvalid() && "nested-name-specifier cannot be invalid");
883 // If the member wasn't found in the current instantiation, or if the
884 // arrow operator was used with a dependent non-pointer object expression,
885 // build a CXXDependentScopeMemberExpr.
886 if (R.wasNotFoundInCurrentInstantiation() ||
887 (R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
888 (SS.isSet() ? SS.getScopeRep().isDependent()
889 : BaseExprType->isDependentType())))
890 return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
891 TemplateKWLoc, FirstQualifierInScope,
892 R.getLookupNameInfo(), TemplateArgs);
893
894 QualType BaseType = BaseExprType;
895 if (IsArrow) {
896 assert(BaseType->isPointerType());
897 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
898 }
899 R.setBaseObjectType(BaseType);
900
901 assert((SS.isEmpty()
902 ? !BaseType->isDependentType() || computeDeclContext(BaseType)
904 "dependent lookup context that isn't the current instantiation?");
905
906 const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
907 DeclarationName MemberName = MemberNameInfo.getName();
908 SourceLocation MemberLoc = MemberNameInfo.getLoc();
909
910 if (R.isAmbiguous())
911 return ExprError();
912
913 // [except.handle]p10: Referring to any non-static member or base class of an
914 // object in the handler for a function-try-block of a constructor or
915 // destructor for that object results in undefined behavior.
916 const auto *FD = getCurFunctionDecl();
917 if (S && BaseExpr && FD &&
919 isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts()) &&
921 Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr)
923
924 if (R.empty()) {
925 ExprResult RetryExpr = ExprError();
926 if (ExtraArgs && !IsArrow && BaseExpr && !BaseExpr->isTypeDependent()) {
927 SFINAETrap Trap(*this, true);
928 ParsedType ObjectType;
929 bool MayBePseudoDestructor = false;
930 RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr, OpLoc,
931 tok::arrow, ObjectType,
932 MayBePseudoDestructor);
933 if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) {
934 CXXScopeSpec TempSS(SS);
935 RetryExpr = ActOnMemberAccessExpr(
936 ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS,
937 TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl);
938 }
939 if (Trap.hasErrorOccurred())
940 RetryExpr = ExprError();
941 }
942
943 // Rederive where we looked up.
944 DeclContext *DC =
945 (SS.isSet() ? computeDeclContext(SS) : computeDeclContext(BaseType));
946 assert(DC);
947
948 if (RetryExpr.isUsable())
949 Diag(OpLoc, diag::err_no_member_overloaded_arrow)
950 << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->");
951 else
952 Diag(R.getNameLoc(), diag::err_no_member)
953 << MemberName << DC
954 << (SS.isSet()
955 ? SS.getRange()
956 : (BaseExpr ? BaseExpr->getSourceRange() : SourceRange()));
957 return RetryExpr;
958 }
959
960 // Diagnose lookups that find only declarations from a non-base
961 // type. This is possible for either qualified lookups (which may
962 // have been qualified with an unrelated type) or implicit member
963 // expressions (which were found with unqualified lookup and thus
964 // may have come from an enclosing scope). Note that it's okay for
965 // lookup to find declarations from a non-base type as long as those
966 // aren't the ones picked by overload resolution.
967 if ((SS.isSet() || !BaseExpr ||
968 (isa<CXXThisExpr>(BaseExpr) &&
969 cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
970 !SuppressQualifierCheck &&
971 CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
972 return ExprError();
973
974 // Construct an unresolved result if we in fact got an unresolved
975 // result.
976 if (R.isOverloadedResult() || R.isUnresolvableResult()) {
977 // Suppress any lookup-related diagnostics; we'll do these when we
978 // pick a member.
979 R.suppressDiagnostics();
980
981 UnresolvedMemberExpr *MemExpr
982 = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(),
983 BaseExpr, BaseExprType,
984 IsArrow, OpLoc,
986 TemplateKWLoc, MemberNameInfo,
987 TemplateArgs, R.begin(), R.end());
988
989 return MemExpr;
990 }
991
992 assert(R.isSingleResult());
993 DeclAccessPair FoundDecl = R.begin().getPair();
994 NamedDecl *MemberDecl = R.getFoundDecl();
995
996 // FIXME: diagnose the presence of template arguments now.
997
998 // If the decl being referenced had an error, return an error for this
999 // sub-expr without emitting another error, in order to avoid cascading
1000 // error cases.
1001 if (MemberDecl->isInvalidDecl())
1002 return ExprError();
1003
1004 // Handle the implicit-member-access case.
1005 if (!BaseExpr) {
1006 // If this is not an instance member, convert to a non-member access.
1007 if (!MemberDecl->isCXXInstanceMember()) {
1008 // We might have a variable template specialization (or maybe one day a
1009 // member concept-id).
1010 if (TemplateArgs || TemplateKWLoc.isValid())
1011 return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/false, TemplateArgs);
1012
1013 return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl,
1014 FoundDecl, TemplateArgs);
1015 }
1016 SourceLocation Loc = R.getNameLoc();
1017 if (SS.getRange().isValid())
1018 Loc = SS.getRange().getBegin();
1019 BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
1020 }
1021
1022 // C++17 [expr.ref]p2, per CWG2813:
1023 // For the first option (dot), if the id-expression names a static member or
1024 // an enumerator, the first expression is a discarded-value expression; if
1025 // the id-expression names a non-static data member, the first expression
1026 // shall be a glvalue.
1027 auto ConvertBaseExprToDiscardedValue = [&] {
1028 assert(getLangOpts().CPlusPlus &&
1029 "Static member / member enumerator outside of C++");
1030 if (IsArrow)
1031 return false;
1032 ExprResult Converted = IgnoredValueConversions(BaseExpr);
1033 if (Converted.isInvalid())
1034 return true;
1035 BaseExpr = Converted.get();
1036 return false;
1037 };
1038 auto ConvertBaseExprToGLValue = [&] {
1039 if (IsArrow || !BaseExpr->isPRValue())
1040 return false;
1041 ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
1042 if (Converted.isInvalid())
1043 return true;
1044 BaseExpr = Converted.get();
1045 return false;
1046 };
1047
1048 // Check the use of this member.
1049 if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
1050 return ExprError();
1051
1052 if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
1053 if (ConvertBaseExprToGLValue())
1054 return ExprError();
1055 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
1056 MemberNameInfo);
1057 }
1058
1059 if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl)) {
1060 // No temporaries are materialized for property references yet.
1061 // They might be materialized when this is transformed into a member call.
1062 // Note that this is slightly different behaviour from MSVC which doesn't
1063 // implement CWG2813 yet: MSVC might materialize an extra temporary if the
1064 // getter or setter function is an explicit object member function.
1065 return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
1066 MemberNameInfo);
1067 }
1068
1069 if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl)) {
1070 if (ConvertBaseExprToGLValue())
1071 return ExprError();
1072 // We may have found a field within an anonymous union or struct
1073 // (C++ [class.union]).
1074 return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
1075 FoundDecl, BaseExpr,
1076 OpLoc);
1077 }
1078
1079 // Static data member
1080 if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
1081 if (ConvertBaseExprToDiscardedValue())
1082 return ExprError();
1083 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1084 SS.getWithLocInContext(Context), TemplateKWLoc, Var,
1085 FoundDecl, /*HadMultipleCandidates=*/false,
1086 MemberNameInfo, Var->getType().getNonReferenceType(),
1088 }
1089
1090 if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
1091 ExprValueKind valueKind;
1092 QualType type;
1093 if (MemberFn->isInstance()) {
1094 valueKind = VK_PRValue;
1095 type = Context.BoundMemberTy;
1096 if (MemberFn->isImplicitObjectMemberFunction() &&
1097 ConvertBaseExprToGLValue())
1098 return ExprError();
1099 } else {
1100 // Static member function
1101 if (ConvertBaseExprToDiscardedValue())
1102 return ExprError();
1103 valueKind = VK_LValue;
1104 type = MemberFn->getType();
1105 }
1106
1107 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1108 SS.getWithLocInContext(Context), TemplateKWLoc,
1109 MemberFn, FoundDecl, /*HadMultipleCandidates=*/false,
1110 MemberNameInfo, type, valueKind, OK_Ordinary);
1111 }
1112 assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
1113
1114 if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
1115 if (ConvertBaseExprToDiscardedValue())
1116 return ExprError();
1117 return BuildMemberExpr(
1118 BaseExpr, IsArrow, OpLoc, SS.getWithLocInContext(Context),
1119 TemplateKWLoc, Enum, FoundDecl, /*HadMultipleCandidates=*/false,
1120 MemberNameInfo, Enum->getType(), VK_PRValue, OK_Ordinary);
1121 }
1122
1123 if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
1124 if (ConvertBaseExprToDiscardedValue())
1125 return ExprError();
1126 if (!TemplateArgs) {
1128 SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), VarTempl, MemberLoc);
1129 return ExprError();
1130 }
1131
1132 DeclResult VDecl =
1133 CheckVarTemplateId(VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(),
1134 *TemplateArgs, /*SetWrittenArgs=*/false);
1135 if (VDecl.isInvalid())
1136 return ExprError();
1137
1138 // Non-dependent member, but dependent template arguments.
1139 if (!VDecl.get())
1141 BaseExpr, BaseExpr->getType(), IsArrow, OpLoc, SS, TemplateKWLoc,
1142 FirstQualifierInScope, MemberNameInfo, TemplateArgs);
1143
1144 VarDecl *Var = cast<VarDecl>(VDecl.get());
1147
1148 return BuildMemberExpr(BaseExpr, IsArrow, OpLoc,
1149 SS.getWithLocInContext(Context), TemplateKWLoc, Var,
1150 FoundDecl, /*HadMultipleCandidates=*/false,
1151 MemberNameInfo, Var->getType().getNonReferenceType(),
1152 VK_LValue, OK_Ordinary, TemplateArgs);
1153 }
1154
1155 // We found something that we didn't expect. Complain.
1156 if (isa<TypeDecl>(MemberDecl))
1157 Diag(MemberLoc, diag::err_typecheck_member_reference_type)
1158 << MemberName << BaseType << int(IsArrow);
1159 else
1160 Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
1161 << MemberName << BaseType << int(IsArrow);
1162
1163 Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
1164 << MemberName;
1165 R.suppressDiagnostics();
1166 return ExprError();
1167}
1168
1169/// Given that normal member access failed on the given expression,
1170/// and given that the expression's type involves builtin-id or
1171/// builtin-Class, decide whether substituting in the redefinition
1172/// types would be profitable. The redefinition type is whatever
1173/// this translation unit tried to typedef to id/Class; we store
1174/// it to the side and then re-use it in places like this.
1176 const ObjCObjectPointerType *opty
1177 = base.get()->getType()->getAs<ObjCObjectPointerType>();
1178 if (!opty) return false;
1179
1180 const ObjCObjectType *ty = opty->getObjectType();
1181
1182 QualType redef;
1183 if (ty->isObjCId()) {
1185 } else if (ty->isObjCClass()) {
1187 } else {
1188 return false;
1189 }
1190
1191 // Do the substitution as long as the redefinition type isn't just a
1192 // possibly-qualified pointer to builtin-id or builtin-Class again.
1193 opty = redef->getAs<ObjCObjectPointerType>();
1194 if (opty && !opty->getObjectType()->getInterface())
1195 return false;
1196
1197 base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
1198 return true;
1199}
1200
1201static bool isRecordType(QualType T) {
1202 return T->isRecordType();
1203}
1205 if (const PointerType *PT = T->getAs<PointerType>())
1206 return PT->getPointeeType()->isRecordType();
1207 return false;
1208}
1209
1212 if (IsArrow && !Base->getType()->isFunctionType())
1214
1215 return CheckPlaceholderExpr(Base);
1216}
1217
1218/// Look up the given member of the given non-type-dependent
1219/// expression. This can return in one of two ways:
1220/// * If it returns a sentinel null-but-valid result, the caller will
1221/// assume that lookup was performed and the results written into
1222/// the provided structure. It will take over from there.
1223/// * Otherwise, the returned expression will be produced in place of
1224/// an ordinary member expression.
1225///
1226/// The ObjCImpDecl bit is a gross hack that will need to be properly
1227/// fixed for ObjC++.
1229 ExprResult &BaseExpr, bool &IsArrow,
1230 SourceLocation OpLoc, CXXScopeSpec &SS,
1231 Decl *ObjCImpDecl, bool HasTemplateArgs,
1232 SourceLocation TemplateKWLoc) {
1233 assert(BaseExpr.get() && "no base expression");
1234
1235 // Perform default conversions.
1236 BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
1237 if (BaseExpr.isInvalid())
1238 return ExprError();
1239
1240 QualType BaseType = BaseExpr.get()->getType();
1241
1242 DeclarationName MemberName = R.getLookupName();
1243 SourceLocation MemberLoc = R.getNameLoc();
1244
1245 // For later type-checking purposes, turn arrow accesses into dot
1246 // accesses. The only access type we support that doesn't follow
1247 // the C equivalence "a->b === (*a).b" is ObjC property accesses,
1248 // and those never use arrows, so this is unaffected.
1249 if (IsArrow) {
1250 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1251 BaseType = Ptr->getPointeeType();
1252 else if (const ObjCObjectPointerType *Ptr =
1253 BaseType->getAs<ObjCObjectPointerType>())
1254 BaseType = Ptr->getPointeeType();
1255 else if (BaseType->isFunctionType())
1256 goto fail;
1257 else if (BaseType->isDependentType())
1258 BaseType = S.Context.DependentTy;
1259 else if (BaseType->isRecordType()) {
1260 // Recover from arrow accesses to records, e.g.:
1261 // struct MyRecord foo;
1262 // foo->bar
1263 // This is actually well-formed in C++ if MyRecord has an
1264 // overloaded operator->, but that should have been dealt with
1265 // by now--or a diagnostic message already issued if a problem
1266 // was encountered while looking for the overloaded operator->.
1267 if (!S.getLangOpts().CPlusPlus) {
1268 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1269 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1270 << FixItHint::CreateReplacement(OpLoc, ".");
1271 }
1272 IsArrow = false;
1273 } else {
1274 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
1275 << BaseType << BaseExpr.get()->getSourceRange();
1276 return ExprError();
1277 }
1278 }
1279
1280 // If the base type is an atomic type, this access is undefined behavior per
1281 // C11 6.5.2.3p5. Instead of giving a typecheck error, we'll warn the user
1282 // about the UB and recover by converting the atomic lvalue into a non-atomic
1283 // lvalue. Because this is inherently unsafe as an atomic operation, the
1284 // warning defaults to an error.
1285 if (const auto *ATy = BaseType->getAs<AtomicType>()) {
1286 S.DiagRuntimeBehavior(OpLoc, BaseExpr.get(),
1287 S.PDiag(diag::warn_atomic_member_access));
1288 BaseType = ATy->getValueType().getUnqualifiedType();
1289 BaseExpr = ImplicitCastExpr::Create(
1290 S.Context, IsArrow ? S.Context.getPointerType(BaseType) : BaseType,
1291 CK_AtomicToNonAtomic, BaseExpr.get(), nullptr,
1292 BaseExpr.get()->getValueKind(), FPOptionsOverride());
1293 }
1294
1295 // Handle field access to simple records.
1296 if (BaseType->getAsRecordDecl()) {
1297 if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow,
1298 SS, HasTemplateArgs, TemplateKWLoc))
1299 return ExprError();
1300
1301 // Returning valid-but-null is how we indicate to the caller that
1302 // the lookup result was filled in. If typo correction was attempted and
1303 // failed, the lookup result will have been cleared--that combined with the
1304 // valid-but-null ExprResult will trigger the appropriate diagnostics.
1305 return ExprResult{};
1306 } else if (BaseType->isDependentType()) {
1307 R.setNotFoundInCurrentInstantiation();
1308 return ExprEmpty();
1309 }
1310
1311 // Handle ivar access to Objective-C objects.
1312 if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
1313 if (!SS.isEmpty() && !SS.isInvalid()) {
1314 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1315 << 1 << SS.getScopeRep()
1317 SS.clear();
1318 }
1319
1321
1322 // There are three cases for the base type:
1323 // - builtin id (qualified or unqualified)
1324 // - builtin Class (qualified or unqualified)
1325 // - an interface
1326 ObjCInterfaceDecl *IDecl = OTy->getInterface();
1327 if (!IDecl) {
1328 if (S.getLangOpts().ObjCAutoRefCount &&
1329 (OTy->isObjCId() || OTy->isObjCClass()))
1330 goto fail;
1331 // There's an implicit 'isa' ivar on all objects.
1332 // But we only actually find it this way on objects of type 'id',
1333 // apparently.
1334 if (OTy->isObjCId() && Member->isStr("isa"))
1335 return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1336 OpLoc, S.Context.getObjCClassType());
1337 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1338 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1339 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1340 goto fail;
1341 }
1342
1343 if (S.RequireCompleteType(OpLoc, BaseType,
1344 diag::err_typecheck_incomplete_tag,
1345 BaseExpr.get()))
1346 return ExprError();
1347
1348 ObjCInterfaceDecl *ClassDeclared = nullptr;
1349 ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1350
1351 if (!IV) {
1352 // Attempt to correct for typos in ivar names.
1353 DeclFilterCCC<ObjCIvarDecl> Validator{};
1354 Validator.IsObjCIvarLookup = IsArrow;
1355 if (TypoCorrection Corrected = S.CorrectTypo(
1356 R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
1357 Validator, CorrectTypoKind::ErrorRecovery, IDecl)) {
1358 IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
1359 S.diagnoseTypo(
1360 Corrected,
1361 S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1362 << IDecl->getDeclName() << MemberName);
1363
1364 // Figure out the class that declares the ivar.
1365 assert(!ClassDeclared);
1366
1367 Decl *D = cast<Decl>(IV->getDeclContext());
1368 if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1369 D = Category->getClassInterface();
1370
1371 if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1372 ClassDeclared = Implementation->getClassInterface();
1373 else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1374 ClassDeclared = Interface;
1375
1376 assert(ClassDeclared && "cannot query interface");
1377 } else {
1378 if (IsArrow &&
1381 S.Diag(MemberLoc, diag::err_property_found_suggest)
1382 << Member << BaseExpr.get()->getType()
1383 << FixItHint::CreateReplacement(OpLoc, ".");
1384 return ExprError();
1385 }
1386
1387 S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1388 << IDecl->getDeclName() << MemberName
1389 << BaseExpr.get()->getSourceRange();
1390 return ExprError();
1391 }
1392 }
1393
1394 assert(ClassDeclared);
1395
1396 // If the decl being referenced had an error, return an error for this
1397 // sub-expr without emitting another error, in order to avoid cascading
1398 // error cases.
1399 if (IV->isInvalidDecl())
1400 return ExprError();
1401
1402 // Check whether we can reference this field.
1403 if (S.DiagnoseUseOfDecl(IV, MemberLoc))
1404 return ExprError();
1407 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1408 if (ObjCMethodDecl *MD = S.getCurMethodDecl())
1409 ClassOfMethodDecl = MD->getClassInterface();
1410 else if (ObjCImpDecl && S.getCurFunctionDecl()) {
1411 // Case of a c-function declared inside an objc implementation.
1412 // FIXME: For a c-style function nested inside an objc implementation
1413 // class, there is no implementation context available, so we pass
1414 // down the context as argument to this routine. Ideally, this context
1415 // need be passed down in the AST node and somehow calculated from the
1416 // AST for a function decl.
1417 if (ObjCImplementationDecl *IMPD =
1418 dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1419 ClassOfMethodDecl = IMPD->getClassInterface();
1420 else if (ObjCCategoryImplDecl* CatImplClass =
1421 dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1422 ClassOfMethodDecl = CatImplClass->getClassInterface();
1423 }
1424 if (!S.getLangOpts().DebuggerSupport) {
1426 if (!declaresSameEntity(ClassDeclared, IDecl) ||
1427 !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
1428 S.Diag(MemberLoc, diag::err_private_ivar_access)
1429 << IV->getDeclName();
1430 } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1431 // @protected
1432 S.Diag(MemberLoc, diag::err_protected_ivar_access)
1433 << IV->getDeclName();
1434 }
1435 }
1436 bool warn = true;
1437 if (S.getLangOpts().ObjCWeak) {
1438 Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1439 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1440 if (UO->getOpcode() == UO_Deref)
1441 BaseExp = UO->getSubExpr()->IgnoreParenCasts();
1442
1443 if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
1444 if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1445 S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
1446 warn = false;
1447 }
1448 }
1449 if (warn) {
1450 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
1451 ObjCMethodFamily MF = MD->getMethodFamily();
1452 warn = (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
1453 !S.ObjC().IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
1454 }
1455 if (warn)
1456 S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
1457 }
1458
1459 ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
1460 IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1461 IsArrow);
1462
1464 if (!S.isUnevaluatedContext() &&
1465 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1466 S.getCurFunction()->recordUseOfWeak(Result);
1467 }
1468
1469 return Result;
1470 }
1471
1472 // Objective-C property access.
1473 const ObjCObjectPointerType *OPT;
1474 if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
1475 if (!SS.isEmpty() && !SS.isInvalid()) {
1476 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1477 << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
1478 SS.clear();
1479 }
1480
1481 // This actually uses the base as an r-value.
1482 BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
1483 if (BaseExpr.isInvalid())
1484 return ExprError();
1485
1486 assert(S.Context.hasSameUnqualifiedType(BaseType,
1487 BaseExpr.get()->getType()));
1488
1490
1491 const ObjCObjectType *OT = OPT->getObjectType();
1492
1493 // id, with and without qualifiers.
1494 if (OT->isObjCId()) {
1495 // Check protocols on qualified interfaces.
1497 if (Decl *PMDecl =
1498 FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
1499 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1500 // Check the use of this declaration
1501 if (S.DiagnoseUseOfDecl(PD, MemberLoc))
1502 return ExprError();
1503
1504 return new (S.Context)
1506 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1507 }
1508
1509 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
1510 Selector SetterSel =
1512 S.PP.getSelectorTable(),
1513 Member);
1514 ObjCMethodDecl *SMD = nullptr;
1515 if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
1516 /*Property id*/ nullptr,
1517 SetterSel, S.Context))
1518 SMD = dyn_cast<ObjCMethodDecl>(SDecl);
1519
1520 return new (S.Context)
1522 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1523 }
1524 }
1525 // Use of id.member can only be for a property reference. Do not
1526 // use the 'id' redefinition in this case.
1527 if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1528 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1529 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1530
1531 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1532 << MemberName << BaseType);
1533 }
1534
1535 // 'Class', unqualified only.
1536 if (OT->isObjCClass()) {
1537 // Only works in a method declaration (??!).
1539 if (!MD) {
1540 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1541 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1542 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1543
1544 goto fail;
1545 }
1546
1547 // Also must look for a getter name which uses property syntax.
1549 ObjCInterfaceDecl *IFace = MD->getClassInterface();
1550 if (!IFace)
1551 goto fail;
1552
1553 ObjCMethodDecl *Getter;
1554 if ((Getter = IFace->lookupClassMethod(Sel))) {
1555 // Check the use of this method.
1556 if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
1557 return ExprError();
1558 } else
1559 Getter = IFace->lookupPrivateMethod(Sel, false);
1560 // If we found a getter then this may be a valid dot-reference, we
1561 // will look for the matching setter, in case it is needed.
1562 Selector SetterSel =
1564 S.PP.getSelectorTable(),
1565 Member);
1566 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1567 if (!Setter) {
1568 // If this reference is in an @implementation, also check for 'private'
1569 // methods.
1570 Setter = IFace->lookupPrivateMethod(SetterSel, false);
1571 }
1572
1573 if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
1574 return ExprError();
1575
1576 if (Getter || Setter) {
1577 return new (S.Context) ObjCPropertyRefExpr(
1578 Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1579 OK_ObjCProperty, MemberLoc, BaseExpr.get());
1580 }
1581
1582 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1583 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1584 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1585
1586 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1587 << MemberName << BaseType);
1588 }
1589
1590 // Normal property access.
1592 OPT, BaseExpr.get(), OpLoc, MemberName, MemberLoc, SourceLocation(),
1593 QualType(), false);
1594 }
1595
1596 if (BaseType->isPackedVectorBoolType(S.Context)) {
1597 // We disallow element access for ext_vector_type bool. There is no way to
1598 // materialize a reference to a vector element as a pointer (each element is
1599 // one bit in the vector).
1600 S.Diag(R.getNameLoc(), diag::err_ext_vector_component_name_illegal)
1601 << MemberName
1602 << (BaseExpr.get() ? BaseExpr.get()->getSourceRange() : SourceRange());
1603 return ExprError();
1604 }
1605
1606 // Handle 'field access' to vectors, such as 'V.xx'.
1607 if (BaseType->isExtVectorType()) {
1608 // FIXME: this expr should store IsArrow.
1610 ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
1611 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
1612 Member, MemberLoc);
1613 if (ret.isNull())
1614 return ExprError();
1615 Qualifiers BaseQ =
1617 ret = S.Context.getQualifiedType(ret, BaseQ);
1618
1619 return new (S.Context)
1620 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
1621 }
1622
1623 if (S.getLangOpts().HLSL && BaseType->isConstantMatrixType()) {
1625 ExprValueKind VK = BaseExpr.get()->getValueKind();
1626 QualType Ret = S.HLSL().checkMatrixComponent(S, BaseType, VK, OpLoc, Member,
1627 MemberLoc);
1628 if (Ret.isNull())
1629 return ExprError();
1630 Qualifiers BaseQ =
1632 Ret = S.Context.getQualifiedType(Ret, BaseQ);
1633
1634 return new (S.Context)
1635 MatrixElementExpr(Ret, VK, BaseExpr.get(), *Member, MemberLoc);
1636 }
1637
1638 // Adjust builtin-sel to the appropriate redefinition type if that's
1639 // not just a pointer to builtin-sel again.
1640 if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
1642 BaseExpr = S.ImpCastExprToType(
1643 BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1644 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1645 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1646 }
1647
1648 // Failure cases.
1649 fail:
1650
1651 // Recover from dot accesses to pointers, e.g.:
1652 // type *foo;
1653 // foo.bar
1654 // This is actually well-formed in two cases:
1655 // - 'type' is an Objective C type
1656 // - 'bar' is a pseudo-destructor name which happens to refer to
1657 // the appropriate pointer type
1658 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1659 if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
1661 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1662 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1663 << FixItHint::CreateReplacement(OpLoc, "->");
1664
1665 if (S.isSFINAEContext())
1666 return ExprError();
1667
1668 // Recurse as an -> access.
1669 IsArrow = true;
1670 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1671 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1672 }
1673 }
1674
1675 // If the user is trying to apply -> or . to a function name, it's probably
1676 // because they forgot parentheses to call that function.
1678 BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1679 /*complain*/ false,
1680 IsArrow ? &isPointerToRecordType : &isRecordType)) {
1681 if (BaseExpr.isInvalid())
1682 return ExprError();
1683 BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1684 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1685 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1686 }
1687
1688 // HLSL supports implicit conversion of scalar types to single element vector
1689 // rvalues in member expressions.
1690 if (S.getLangOpts().HLSL && BaseType->isScalarType()) {
1691 QualType VectorTy = S.Context.getExtVectorType(BaseType, 1);
1692 BaseExpr = S.ImpCastExprToType(BaseExpr.get(), VectorTy, CK_VectorSplat,
1693 BaseExpr.get()->getValueKind());
1694 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS, ObjCImpDecl,
1695 HasTemplateArgs, TemplateKWLoc);
1696 }
1697
1698 S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
1699 << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
1700
1701 return ExprError();
1702}
1703
1705 SourceLocation OpLoc,
1706 tok::TokenKind OpKind, CXXScopeSpec &SS,
1707 SourceLocation TemplateKWLoc,
1708 UnqualifiedId &Id, Decl *ObjCImpDecl) {
1709 // Warn about the explicit constructor calls Microsoft extension.
1710 if (getLangOpts().MicrosoftExt &&
1713 diag::ext_ms_explicit_constructor_call);
1714
1715 TemplateArgumentListInfo TemplateArgsBuffer;
1716
1717 // Decompose the name into its component parts.
1718 DeclarationNameInfo NameInfo;
1719 const TemplateArgumentListInfo *TemplateArgs;
1720 DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1721 NameInfo, TemplateArgs);
1722
1723 bool IsArrow = (OpKind == tok::arrow);
1724
1725 if (getLangOpts().HLSL && IsArrow)
1726 return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 2);
1727
1728 NamedDecl *FirstQualifierInScope
1729 = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
1730
1731 // This is a postfix expression, so get rid of ParenListExprs.
1733 if (Result.isInvalid()) return ExprError();
1734 Base = Result.get();
1735
1736 ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
1738 Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc,
1739 FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs);
1740
1741 if (!Res.isInvalid()) {
1742 if (MemberExpr *ME = dyn_cast<MemberExpr>(Res.get())) {
1743 CheckMemberAccessOfNoDeref(ME);
1744
1745 if (getLangOpts().HLSL) {
1746 QualType Ty = Res.get()->getType();
1748 if (!HLSL().ActOnResourceMemberAccessExpr(ME))
1749 Res = ExprError();
1750 }
1751 }
1752 }
1753 return Res;
1754}
1755
1756void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
1758 return;
1759
1760 QualType ResultTy = E->getType();
1761
1762 // Member accesses have four cases:
1763 // 1: non-array member via "->": dereferences
1764 // 2: non-array member via ".": nothing interesting happens
1765 // 3: array member access via "->": nothing interesting happens
1766 // (this returns an array lvalue and does not actually dereference memory)
1767 // 4: array member access via ".": *adds* a layer of indirection
1768 if (ResultTy->isArrayType()) {
1769 if (!E->isArrow()) {
1770 // This might be something like:
1771 // (*structPtr).arrayMember
1772 // which behaves roughly like:
1773 // &(*structPtr).pointerMember
1774 // in that the apparent dereference in the base expression does not
1775 // actually happen.
1776 CheckAddressOfNoDeref(E->getBase());
1777 }
1778 } else if (E->isArrow()) {
1779 if (const auto *Ptr = dyn_cast<PointerType>(
1781 if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
1782 ExprEvalContexts.back().PossibleDerefs.insert(E);
1783 }
1784 }
1785}
1786
1788Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1789 SourceLocation OpLoc, const CXXScopeSpec &SS,
1790 FieldDecl *Field, DeclAccessPair FoundDecl,
1791 const DeclarationNameInfo &MemberNameInfo) {
1792 // x.a is an l-value if 'a' has a reference type. Otherwise:
1793 // x.a is an l-value/x-value/pr-value if the base is (and note
1794 // that *x is always an l-value), except that if the base isn't
1795 // an ordinary object then we must have an rvalue.
1798 if (!IsArrow) {
1799 if (BaseExpr->getObjectKind() == OK_Ordinary)
1800 VK = BaseExpr->getValueKind();
1801 else
1802 VK = VK_PRValue;
1803 }
1804 if (VK != VK_PRValue && Field->isBitField())
1805 OK = OK_BitField;
1806
1807 // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1808 QualType MemberType = Field->getType();
1809 if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1810 MemberType = Ref->getPointeeType();
1811 VK = VK_LValue;
1812 } else {
1813 QualType BaseType = BaseExpr->getType();
1814 if (IsArrow) BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1815
1816 Qualifiers BaseQuals = BaseType.getQualifiers();
1817
1818 // GC attributes are never picked up by members.
1819 BaseQuals.removeObjCGCAttr();
1820
1821 // CVR attributes from the base are picked up by members,
1822 // except that 'mutable' members don't pick up 'const'.
1823 if (Field->isMutable()) BaseQuals.removeConst();
1824
1825 // HLSL resource types do not pick up address space qualifiers from the
1826 // base.
1827 if (getLangOpts().HLSL && (MemberType->isHLSLResourceRecord() ||
1828 MemberType->isHLSLResourceRecordArray()))
1829 BaseQuals.removeAddressSpace();
1830
1831 Qualifiers MemberQuals =
1832 Context.getCanonicalType(MemberType).getQualifiers();
1833
1834 assert(!MemberQuals.hasAddressSpace());
1835
1836 Qualifiers Combined = BaseQuals + MemberQuals;
1837 if (Combined != MemberQuals)
1838 MemberType = Context.getQualifiedType(MemberType, Combined);
1839
1840 // Pick up NoDeref from the base in case we end up using AddrOf on the
1841 // result. E.g. the expression
1842 // &someNoDerefPtr->pointerMember
1843 // should be a noderef pointer again.
1844 if (BaseType->hasAttr(attr::NoDeref))
1845 MemberType =
1846 Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
1847 }
1848
1849 auto isDefaultedSpecialMember = [this](const DeclContext *Ctx) {
1850 auto *Method = dyn_cast<CXXMethodDecl>(CurContext);
1851 if (!Method || !Method->isDefaulted())
1852 return false;
1853
1855 };
1856
1857 // Implicit special members should not mark fields as used.
1858 if (!isDefaultedSpecialMember(CurContext))
1859 UnusedPrivateFields.remove(Field);
1860
1862 FoundDecl, Field);
1863 if (Base.isInvalid())
1864 return ExprError();
1865
1866 // Build a reference to a private copy for non-static data members in
1867 // non-static member functions, privatized by OpenMP constructs.
1868 if (getLangOpts().OpenMP && IsArrow &&
1869 !CurContext->isDependentContext() &&
1870 isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
1871 if (auto *PrivateCopy = OpenMP().isOpenMPCapturedDecl(Field)) {
1872 return OpenMP().getOpenMPCapturedExpr(PrivateCopy, VK, OK,
1873 MemberNameInfo.getLoc());
1874 }
1875 }
1876
1877 return BuildMemberExpr(
1878 Base.get(), IsArrow, OpLoc, SS.getWithLocInContext(Context),
1879 /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1880 /*HadMultipleCandidates=*/false, MemberNameInfo, MemberType, VK, OK);
1881}
1882
1885 SourceLocation TemplateKWLoc,
1886 LookupResult &R,
1887 const TemplateArgumentListInfo *TemplateArgs,
1888 bool IsKnownInstance, const Scope *S) {
1889 assert(!R.empty() && !R.isAmbiguous());
1890
1891 SourceLocation loc = R.getNameLoc();
1892
1893 // If this is known to be an instance access, go ahead and build an
1894 // implicit 'this' expression now.
1895 QualType ThisTy = getCurrentThisType();
1896 assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
1897
1898 Expr *baseExpr = nullptr; // null signifies implicit access
1899 if (IsKnownInstance) {
1900 SourceLocation Loc = R.getNameLoc();
1901 if (SS.getRange().isValid())
1902 Loc = SS.getRange().getBegin();
1903 baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
1904 }
1905
1907 baseExpr, ThisTy,
1908 /*OpLoc=*/SourceLocation(),
1909 /*IsArrow=*/!getLangOpts().HLSL, SS, TemplateKWLoc,
1910 /*FirstQualifierInScope=*/nullptr, R, TemplateArgs, S);
1911}
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Record Record
Definition MachO.h:31
Defines the clang::Preprocessor interface.
static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base)
Given that normal member access failed on the given expression, and given that the expression's type ...
static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, Expr *BaseExpr, QualType RTy, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, bool HasTemplateArgs, SourceLocation TemplateKWLoc)
static bool isPointerToRecordType(QualType T)
static Decl * FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl *PDecl, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
@ IMA_Mixed_Unrelated
The reference may be to an instance member, but it is invalid if so, because the context is from an u...
@ IMA_Mixed
The reference may be an implicit instance member access.
@ IMA_Error_Unrelated
All possible referrents are instance members of an unrelated class.
@ IMA_Unresolved
The reference may be to an unresolved using declaration.
@ IMA_Abstract
The reference is a contextually-permitted abstract member reference.
@ IMA_Mixed_StaticOrExplicitContext
The reference may be to an instance member, but it might be invalid if so, because the context is not...
@ IMA_Instance
The reference is definitely an implicit instance member access.
@ IMA_Error_StaticOrExplicitContext
All possible referrents are instance members and the current context is not an instance method.
@ IMA_Unresolved_StaticOrExplicitContext
The reference may be to an unresolved using declaration and the context is not an instance method.
@ IMA_Dependent
Whether the context is static is dependent on the enclosing template (i.e.
@ IMA_Field_Uneval_Context
@ IMA_Static
The reference is definitely not an instance member access.
static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record, const BaseSet &Bases)
Determines if the given class is provably not derived from all of the prospective base classes.
static void diagnoseInstanceReference(Sema &SemaRef, const CXXScopeSpec &SS, NamedDecl *Rep, const DeclarationNameInfo &nameInfo)
Diagnose a reference to a field with no object available.
static bool isRecordType(QualType T)
static QualType CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK, SourceLocation OpLoc, const IdentifierInfo *CompName, SourceLocation CompLoc)
Check an ext-vector component access expression.
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > BaseSet
static Decl * FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, IdentifierInfo *Member, const Selector &Sel, ASTContext &Context)
static void DiagnoseQualifiedMemberReference(Sema &SemaRef, Expr *BaseExpr, QualType BaseType, const CXXScopeSpec &SS, NamedDecl *rep, const DeclarationNameInfo &nameInfo)
We know that the given qualified member reference points only to declarations which do not belong to ...
static bool IsValidOpenCLComponentSwizzleLength(unsigned len)
static ExprResult BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, const CXXScopeSpec &SS, MSPropertyDecl *PD, const DeclarationNameInfo &NameInfo)
static bool IsRGBA(char c)
Determine whether input char is from rgba component set.
static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, const LookupResult &R)
The given lookup names class member(s) and is not being used for an address-of-member expression.
static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, Decl *ObjCImpDecl, bool HasTemplateArgs, SourceLocation TemplateKWLoc)
Look up the given member of the given non-type-dependent expression.
static bool IsInFnTryBlockHandler(const Scope *S)
Determine if the given scope is within a function-try-block handler.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getObjCClassType() const
Represents the Objective-C Class type.
QualType getObjCSelRedefinitionType() const
Retrieve the type that 'SEL' has been defined to, which may be different from the built-in 'SEL' if '...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType DependentTy
CanQualType PseudoObjectTy
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getObjCClassRedefinitionType() const
Retrieve the type that Class has been defined to, which may be different from the built-in Class if C...
QualType getObjCIdRedefinitionType() const
Retrieve the type that id has been defined to, which may be different from the built-in id if id has ...
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
bool isUsable() const
Definition Ownership.h:169
static CXXDependentScopeMemberExpr * Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs)
Definition ExprCXX.cpp:1550
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is provably not derived from the type Base.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:522
Represents a C++ nested-name-specifier or a global scope specifier.
Definition DeclSpec.h:74
SourceRange getRange() const
Definition DeclSpec.h:80
bool isSet() const
Deprecated.
Definition DeclSpec.h:199
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition DeclSpec.h:95
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition DeclSpec.cpp:123
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition DeclSpec.h:184
bool isEmpty() const
No scope specifier.
Definition DeclSpec.h:179
Qualifiers getQualifiers() const
Retrieve all qualifiers.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition DeclBase.h:2251
bool isRecord() const
Definition DeclBase.h:2202
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context semantically encloses the declaration context DC.
DeclContext * getNonTransparentContext()
Simple template class for restricting typo correction candidates to ones having a single Decl* of the...
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isInvalidDecl() const
Definition DeclBase.h: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:960
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3438
This represents one expression.
Definition Expr.h:112
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition Expr.cpp:3095
void setType(QualType t)
Definition Expr.h:145
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Definition Expr.h:447
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition Expr.cpp:3090
bool isPRValue() const
Definition Expr.h:285
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition Expr.h:454
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3070
QualType getType() const
Definition Expr.h:144
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6609
ExtVectorType - Extended vector type.
Definition TypeBase.h:4317
bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const
Definition TypeBase.h:4370
static int getNumericAccessorIdx(char c)
Definition TypeBase.h:4335
static int getPointAccessorIdx(char c)
Definition TypeBase.h:4325
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
Definition Decl.h:3175
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:141
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition Diagnostic.h:130
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:104
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5357
One of these records is kept for each identifier that is lexed.
unsigned getLength() const
Efficiently return the length of this identifier info.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition Expr.cpp:2073
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3482
chain_iterator chain_end() const
Definition Decl.h:3505
chain_iterator chain_begin() const
Definition Decl.h:3504
VarDecl * getVarDecl() const
Definition Decl.h:3514
ArrayRef< NamedDecl * >::const_iterator chain_iterator
Definition Decl.h:3501
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
iterator begin(Source *source, bool LocalOnly=false)
Represents the results of name lookup.
Definition Lookup.h:147
UnresolvedSetImpl::iterator iterator
Definition Lookup.h:154
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4360
A member reference to an MSPropertyDecl.
Definition ExprCXX.h:937
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3367
void setHadMultipleCandidates(bool V=true)
Sets the flag telling whether this expression refers to a method that was resolved from an overloaded...
Definition Expr.h:3577
static MemberExpr * Create(const ASTContext &C, Expr *Base, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, DeclAccessPair FoundDecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR)
Definition Expr.cpp:1750
Expr * getBase() const
Definition Expr.h:3444
bool isArrow() const
Definition Expr.h:3551
This represents a decl that may have a name.
Definition Decl.h:274
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition Decl.h:487
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition Decl.cpp:1975
A C++ nested-name-specifier augmented with source location information.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
ObjCPropertyDecl * FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const
FindPropertyDeclaration - Finds declaration of the property given its name in 'PropertyId' and return...
Definition DeclObjC.cpp:247
ObjCMethodDecl * getInstanceMethod(Selector Sel, bool AllowHidden=false) const
Definition DeclObjC.h:1066
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2597
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
ObjCMethodDecl * lookupClassMethod(Selector Sel) const
Lookup a class method for a given selector.
Definition DeclObjC.h:1852
ObjCIvarDecl * lookupInstanceVariable(IdentifierInfo *IVarName, ObjCInterfaceDecl *&ClassDeclared)
Definition DeclObjC.cpp:634
ObjCMethodDecl * lookupPrivateMethod(const Selector &Sel, bool Instance=true) const
Lookup a method in the classes implementation hierarchy.
Definition DeclObjC.cpp:753
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition DeclObjC.h:1810
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition ExprObjC.h:1529
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
AccessControl getAccessControl() const
Definition DeclObjC.h:2000
QualType getUsageType(QualType objectType) const
Retrieve the type of this instance variable when viewed as a member of a specific object type.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:580
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:8049
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Definition TypeBase.h:8086
qual_range quals() const
Definition TypeBase.h:8168
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:648
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
protocol_range protocols() const
Definition DeclObjC.h:2161
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3378
QualType getPointeeType() const
Definition TypeBase.h:3388
IdentifierTable & getIdentifierTable()
SelectorTable & getSelectorTable()
A (possibly-)qualified type.
Definition TypeBase.h:937
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
Definition TypeBase.h:1302
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8471
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
Definition TypeBase.h:1444
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8616
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
@ OCL_Weak
Reading or writing from this object requires a barrier call.
Definition TypeBase.h:364
bool hasAddressSpace() const
Definition TypeBase.h:570
void removeObjCGCAttr()
Definition TypeBase.h:523
void removeAddressSpace()
Definition TypeBase.h:596
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3623
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
const Scope * getFnParent() const
getFnParent - Return the closest scope that is a function body.
Definition Scope.h:291
unsigned getFlags() const
getFlags - Return the flags for this scope.
Definition Scope.h:271
bool isFnTryCatchScope() const
Determine whether this scope is a function-level C++ try or catch scope.
Definition Scope.h:608
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition Scope.h:287
@ TryScope
This is the scope of a C++ try statement.
Definition Scope.h:105
static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)
Return the default setter selector for the given identifier.
Selector getNullarySelector(const IdentifierInfo *ID)
Smart pointer class that efficiently represents Objective-C method names.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition SemaBase.cpp:33
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
QualType checkMatrixComponent(Sema &S, QualType baseType, ExprValueKind &VK, SourceLocation OpLoc, const IdentifierInfo *CompName, SourceLocation CompLoc)
ExprResult HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Expr *BaseExpr, SourceLocation OpLoc, DeclarationName MemberName, SourceLocation MemberLoc, SourceLocation SuperLoc, QualType SuperType, bool Super)
HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an objective C interface.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12551
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Definition Sema.h:12585
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition Sema.h:1141
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition Sema.h:9423
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:1533
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:4954
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:1725
ASTContext & Context
Definition Sema.h:1308
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:226
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:1518
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:2910
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition SemaExpr.cpp:759
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:762
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition Sema.cpp:1730
const LangOptions & getLangOpts() const
Definition Sema.h:932
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
NonOdrUseReason getNonOdrUseReasonInCurrentContext(ValueDecl *D)
If D cannot be odr-used in the current expression evaluation context, return a reason explaining why.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, QualType ObjectType, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
Preprocessor & PP
Definition Sema.h:1307
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:6582
SemaHLSL & HLSL()
Definition Sema.h:1483
sema::FunctionScopeInfo * getCurFunction() const
Definition Sema.h:1341
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:644
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:1446
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
Definition Sema.h:8261
DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const
If AllowLambda is true, treat lambda as function.
Definition Sema.cpp:1705
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:8528
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
ExprResult ActOnDependentMemberExpr(Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs)
bool isThisOutsideMemberFunctionBody(QualType BaseType)
Determine whether the given type is the type of *this that is used outside of the body of a member fu...
ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, const Scope *S)
Builds an expression which might be an implicit member expression.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExternalSemaSource * getExternalSource() const
Definition Sema.h:942
bool isSFINAEContext() const
Definition Sema.h:13793
@ UnevaluatedAbstract
The current expression occurs within an unevaluated operand that unconditionally permits abstract ref...
Definition Sema.h:6805
@ UnevaluatedList
The current expression occurs within a braced-init-list within an unevaluated operand.
Definition Sema.h:6795
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
Definition Sema.h:6810
@ DiscardedStatement
The current expression occurs within a discarded statement.
Definition Sema.h:6800
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
Definition Sema.h:6820
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
Definition Sema.h:6789
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
Definition Sema.h:6815
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
Definition Sema.h:6830
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:8401
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:1310
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
Definition SemaExpr.cpp:520
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:8767
bool isPointerType() const
Definition TypeBase.h:8668
bool isObjCSelType() const
Definition TypeBase.h:8892
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9328
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:754
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2832
bool isHLSLResourceRecord() const
Definition Type.cpp:5448
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
bool isRecordType() const
Definition TypeBase.h:8795
bool isHLSLResourceRecordArray() const
Definition Type.cpp:5452
Simple class containing the result of Sema::CorrectTypo.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
Represents a C++ unqualified-id that has been parsed.
Definition DeclSpec.h:1033
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
Definition DeclSpec.h:1242
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Definition DeclSpec.h:1115
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
Definition ExprCXX.cpp:432
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition ExprCXX.h:4123
static UnresolvedMemberExpr * Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition ExprCXX.cpp:1652
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation=SourceLocation())
For a static data member that was instantiated from a static data member of a class template,...
Definition Decl.cpp:2920
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:2792
Declaration of a variable template.
unsigned getNumElements() const
Definition TypeBase.h:4240
QualType getElementType() const
Definition TypeBase.h:4239
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Record that a weak object was accessed.
Definition ScopeInfo.h:1094
Definition SPIR.cpp:47
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition TokenKinds.h:25
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition Specifiers.h:150
@ 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:162
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition Specifiers.h:152
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
Definition Specifiers.h:155
@ IK_ConstructorName
A constructor name.
Definition DeclSpec.h:1019
ActionResult< Decl * > DeclResult
Definition Ownership.h:255
ObjCMethodFamily
A family of Objective-C methods.
ExprResult ExprEmpty()
Definition Ownership.h:272
@ Result
The result type of a method or function.
Definition TypeBase.h:905
ActionResult< CXXBaseSpecifier * > BaseResult
Definition Ownership.h:252
ExprResult ExprError()
Definition Ownership.h:265
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition Specifiers.h:133
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:136
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1301
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
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:5961
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5977
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5970
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.