Bug Summary

File:build/source/clang/lib/Sema/SemaExprMember.cpp
Warning:line 380, column 12
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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