blob: 2f9c8d6ee2135289ad7960abafd8a35cae45d426 [file] [log] [blame]
Douglas Gregor5476205b2011-06-23 00:49:38 +00001//===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Douglas Gregor5476205b2011-06-23 00:49:38 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis member access expressions.
10//
11//===----------------------------------------------------------------------===//
Kaelyn Takatafe408a72014-10-27 18:07:46 +000012#include "clang/Sema/Overload.h"
Faisal Valia17d19f2013-11-07 05:17:06 +000013#include "clang/AST/ASTLambda.h"
Douglas Gregor5476205b2011-06-23 00:49:38 +000014#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"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/Sema/Lookup.h"
21#include "clang/Sema/Scope.h"
22#include "clang/Sema/ScopeInfo.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000023#include "clang/Sema/SemaInternal.h"
Douglas Gregor5476205b2011-06-23 00:49:38 +000024
25using namespace clang;
26using namespace sema;
27
Richard Smithd80b2d52012-11-22 00:24:47 +000028typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> BaseSet;
Richard Smithd80b2d52012-11-22 00:24:47 +000029
Douglas Gregor5476205b2011-06-23 00:49:38 +000030/// Determines if the given class is provably not derived from all of
31/// the prospective base classes.
Richard Smithd80b2d52012-11-22 00:24:47 +000032static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record,
33 const BaseSet &Bases) {
Benjamin Kramer6e4f6e12015-07-25 15:07:25 +000034 auto BaseIsNotInSet = [&Bases](const CXXRecordDecl *Base) {
35 return !Bases.count(Base->getCanonicalDecl());
36 };
37 return BaseIsNotInSet(Record) && Record->forallBases(BaseIsNotInSet);
Douglas Gregor5476205b2011-06-23 00:49:38 +000038}
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
Eli Friedman7bda7f72012-01-18 03:53:45 +000047 /// The reference may be to an instance member, but it might be invalid if
Douglas Gregor5476205b2011-06-23 00:49:38 +000048 /// 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
John McCallf413f5e2013-05-03 00:10:13 +000061 /// The reference is a contextually-permitted abstract member reference.
62 IMA_Abstract,
63
Douglas Gregor5476205b2011-06-23 00:49:38 +000064 /// The reference may be to an unresolved using declaration and the
65 /// context is not an instance method.
66 IMA_Unresolved_StaticContext,
67
Eli Friedman456f0182012-01-20 01:26:23 +000068 // 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,
Eli Friedman7bda7f72012-01-18 03:53:45 +000072
Douglas Gregor5476205b2011-06-23 00:49:38 +000073 /// 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
Eli Friedman7bda7f72012-01-18 03:53:45 +000085/// instance member. This is best-effort in dependent contexts; it is okay to
Douglas Gregor5476205b2011-06-23 00:49:38 +000086/// conservatively answer "yes", in which case some errors will simply
87/// not be caught until template-instantiation.
88static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
Douglas Gregor5476205b2011-06-23 00:49:38 +000089 const LookupResult &R) {
90 assert(!R.empty() && (*R.begin())->isCXXClassMember());
91
92 DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
93
Douglas Gregor3024f072012-04-16 07:05:22 +000094 bool isStaticContext = SemaRef.CXXThisTypeOverride.isNull() &&
95 (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic());
Douglas Gregor5476205b2011-06-23 00:49:38 +000096
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;
Eli Friedman7bda7f72012-01-18 03:53:45 +0000102 bool isField = false;
Richard Smithd80b2d52012-11-22 00:24:47 +0000103 BaseSet Classes;
Faisal Vali55bc3892017-08-27 19:00:08 +0000104 for (NamedDecl *D : R) {
105 // Look through any using decls.
106 D = D->getUnderlyingDecl();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000107
Faisal Vali55bc3892017-08-27 19:00:08 +0000108 if (D->isCXXInstanceMember()) {
109 isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
110 isa<IndirectFieldDecl>(D);
111
112 CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
Douglas Gregor5476205b2011-06-23 00:49:38 +0000113 Classes.insert(R->getCanonicalDecl());
Reid Kleckner077fe122015-10-20 18:12:08 +0000114 } else
Douglas Gregor5476205b2011-06-23 00:49:38 +0000115 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;
Fangrui Song6907ce22018-07-30 19:24:48 +0000122
John McCallf413f5e2013-05-03 00:10:13 +0000123 // 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);
134 switch (SemaRef.ExprEvalContexts.back().Context) {
Faisal Valid143a0c2017-04-01 21:30:49 +0000135 case Sema::ExpressionEvaluationContext::Unevaluated:
136 case Sema::ExpressionEvaluationContext::UnevaluatedList:
John McCallf413f5e2013-05-03 00:10:13 +0000137 if (isField && SemaRef.getLangOpts().CPlusPlus11)
138 AbstractInstanceResult = IMA_Field_Uneval_Context;
139 break;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000140
Faisal Valid143a0c2017-04-01 21:30:49 +0000141 case Sema::ExpressionEvaluationContext::UnevaluatedAbstract:
John McCallf413f5e2013-05-03 00:10:13 +0000142 AbstractInstanceResult = IMA_Abstract;
143 break;
144
Faisal Valid143a0c2017-04-01 21:30:49 +0000145 case Sema::ExpressionEvaluationContext::DiscardedStatement:
146 case Sema::ExpressionEvaluationContext::ConstantEvaluated:
147 case Sema::ExpressionEvaluationContext::PotentiallyEvaluated:
148 case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
John McCallf413f5e2013-05-03 00:10:13 +0000149 break;
Richard Smitheae99682012-02-25 10:04:07 +0000150 }
151
Douglas Gregor5476205b2011-06-23 00:49:38 +0000152 // If the current context is not an instance method, it can't be
153 // an implicit member reference.
154 if (isStaticContext) {
155 if (hasNonInstance)
Richard Smitheae99682012-02-25 10:04:07 +0000156 return IMA_Mixed_StaticContext;
157
John McCallf413f5e2013-05-03 00:10:13 +0000158 return AbstractInstanceResult ? AbstractInstanceResult
159 : IMA_Error_StaticContext;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000160 }
161
162 CXXRecordDecl *contextClass;
163 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
164 contextClass = MD->getParent()->getCanonicalDecl();
165 else
166 contextClass = cast<CXXRecordDecl>(DC);
167
Fangrui Song6907ce22018-07-30 19:24:48 +0000168 // [class.mfct.non-static]p3:
Douglas Gregor5476205b2011-06-23 00:49:38 +0000169 // ...is used in the body of a non-static member function of class X,
170 // if name lookup (3.4.1) resolves the name in the id-expression to a
171 // non-static non-type member of some class C [...]
172 // ...if C is not X or a base class of X, the class member access expression
173 // is ill-formed.
174 if (R.getNamingClass() &&
DeLesley Hutchins5b330db2012-02-25 00:11:55 +0000175 contextClass->getCanonicalDecl() !=
Richard Smithd80b2d52012-11-22 00:24:47 +0000176 R.getNamingClass()->getCanonicalDecl()) {
177 // If the naming class is not the current context, this was a qualified
178 // member name lookup, and it's sufficient to check that we have the naming
179 // class as a base class.
180 Classes.clear();
Richard Smithb2c5f962012-11-22 00:40:54 +0000181 Classes.insert(R.getNamingClass()->getCanonicalDecl());
Richard Smithd80b2d52012-11-22 00:24:47 +0000182 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000183
184 // If we can prove that the current context is unrelated to all the
185 // declaring classes, it can't be an implicit member reference (in
186 // which case it's an error if any of those members are selected).
Richard Smithd80b2d52012-11-22 00:24:47 +0000187 if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
Richard Smith2a986112012-02-25 10:20:59 +0000188 return hasNonInstance ? IMA_Mixed_Unrelated :
John McCallf413f5e2013-05-03 00:10:13 +0000189 AbstractInstanceResult ? AbstractInstanceResult :
190 IMA_Error_Unrelated;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000191
192 return (hasNonInstance ? IMA_Mixed : IMA_Instance);
193}
194
195/// Diagnose a reference to a field with no object available.
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000196static void diagnoseInstanceReference(Sema &SemaRef,
197 const CXXScopeSpec &SS,
198 NamedDecl *Rep,
199 const DeclarationNameInfo &nameInfo) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000200 SourceLocation Loc = nameInfo.getLoc();
201 SourceRange Range(Loc);
202 if (SS.isSet()) Range.setBegin(SS.getRange().getBegin());
Eli Friedman7bda7f72012-01-18 03:53:45 +0000203
Reid Klecknerae628962014-12-18 00:42:51 +0000204 // Look through using shadow decls and aliases.
205 Rep = Rep->getUnderlyingDecl();
206
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000207 DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();
Richard Smithfa0a1f52012-04-05 01:13:04 +0000208 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);
Craig Topperc3ec1492014-05-26 06:22:03 +0000209 CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000210 CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext());
211
212 bool InStaticMethod = Method && Method->isStatic();
213 bool IsField = isa<FieldDecl>(Rep) || isa<IndirectFieldDecl>(Rep);
214
215 if (IsField && InStaticMethod)
216 // "invalid use of member 'x' in static member function"
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000217 SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method)
Richard Smithfa0a1f52012-04-05 01:13:04 +0000218 << Range << nameInfo.getName();
219 else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod &&
220 !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass))
221 // Unqualified lookup in a non-static member function found a member of an
222 // enclosing class.
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000223 SemaRef.Diag(Loc, diag::err_nested_non_static_member_use)
224 << IsField << RepClass << nameInfo.getName() << ContextClass << Range;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000225 else if (IsField)
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000226 SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use)
227 << nameInfo.getName() << Range;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000228 else
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000229 SemaRef.Diag(Loc, diag::err_member_call_without_object)
230 << Range;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000231}
232
233/// Builds an expression which might be an implicit member expression.
234ExprResult
235Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000236 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000237 LookupResult &R,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000238 const TemplateArgumentListInfo *TemplateArgs,
239 const Scope *S) {
Reid Klecknerae628962014-12-18 00:42:51 +0000240 switch (ClassifyImplicitMemberAccess(*this, R)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000241 case IMA_Instance:
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000242 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000243
244 case IMA_Mixed:
Faisal Valic3ef5322017-08-29 03:04:13 +0000245 case IMA_Mixed_Unrelated:
Douglas Gregor5476205b2011-06-23 00:49:38 +0000246 case IMA_Unresolved:
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000247 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
248 S);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000249
Richard Smith2a986112012-02-25 10:20:59 +0000250 case IMA_Field_Uneval_Context:
251 Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
252 << R.getLookupNameInfo().getName();
Adrian Prantlf3b3ccd2017-12-19 22:06:11 +0000253 LLVM_FALLTHROUGH;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000254 case IMA_Static:
John McCallf413f5e2013-05-03 00:10:13 +0000255 case IMA_Abstract:
Douglas Gregor5476205b2011-06-23 00:49:38 +0000256 case IMA_Mixed_StaticContext:
257 case IMA_Unresolved_StaticContext:
Abramo Bagnara65f7c3d2012-02-06 14:31:00 +0000258 if (TemplateArgs || TemplateKWLoc.isValid())
259 return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000260 return BuildDeclarationNameExpr(SS, R, false);
261
262 case IMA_Error_StaticContext:
263 case IMA_Error_Unrelated:
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000264 diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(),
Douglas Gregor5476205b2011-06-23 00:49:38 +0000265 R.getLookupNameInfo());
266 return ExprError();
267 }
268
269 llvm_unreachable("unexpected instance member access kind");
Douglas Gregor5476205b2011-06-23 00:49:38 +0000270}
271
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000272/// Determine whether input char is from rgba component set.
273static bool
274IsRGBA(char c) {
275 switch (c) {
276 case 'r':
277 case 'g':
278 case 'b':
279 case 'a':
280 return true;
281 default:
282 return false;
283 }
284}
285
Egor Churaev392a5072017-03-21 13:20:57 +0000286// OpenCL v1.1, s6.1.7
287// The component swizzle length must be in accordance with the acceptable
288// vector sizes.
289static bool IsValidOpenCLComponentSwizzleLength(unsigned len)
290{
291 return (len >= 1 && len <= 4) || len == 8 || len == 16;
292}
293
Douglas Gregor5476205b2011-06-23 00:49:38 +0000294/// Check an ext-vector component access expression.
295///
296/// VK should be set in advance to the value kind of the base
297/// expression.
298static QualType
299CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
300 SourceLocation OpLoc, const IdentifierInfo *CompName,
301 SourceLocation CompLoc) {
302 // FIXME: Share logic with ExtVectorElementExpr::containsDuplicateElements,
303 // see FIXME there.
304 //
305 // FIXME: This logic can be greatly simplified by splitting it along
306 // halving/not halving and reworking the component checking.
307 const ExtVectorType *vecType = baseType->getAs<ExtVectorType>();
308
309 // The vector accessor can't exceed the number of elements.
310 const char *compStr = CompName->getNameStart();
311
312 // This flag determines whether or not the component is one of the four
313 // special names that indicate a subset of exactly half the elements are
314 // to be selected.
315 bool HalvingSwizzle = false;
316
317 // This flag determines whether or not CompName has an 's' char prefix,
318 // indicating that it is a string of hex values to be used as vector indices.
Fariborz Jahanian275542a2014-04-03 19:43:01 +0000319 bool HexSwizzle = (*compStr == 's' || *compStr == 'S') && compStr[1];
Douglas Gregor5476205b2011-06-23 00:49:38 +0000320
321 bool HasRepeated = false;
322 bool HasIndex[16] = {};
323
324 int Idx;
325
326 // Check that we've found one of the special components, or that the component
327 // names must come from the same set.
328 if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
329 !strcmp(compStr, "even") || !strcmp(compStr, "odd")) {
330 HalvingSwizzle = true;
331 } else if (!HexSwizzle &&
332 (Idx = vecType->getPointAccessorIdx(*compStr)) != -1) {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000333 bool HasRGBA = IsRGBA(*compStr);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000334 do {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000335 // Ensure that xyzw and rgba components don't intermingle.
336 if (HasRGBA != IsRGBA(*compStr))
337 break;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000338 if (HasIndex[Idx]) HasRepeated = true;
339 HasIndex[Idx] = true;
340 compStr++;
341 } while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1);
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000342
343 // Emit a warning if an rgba selector is used earlier than OpenCL 2.2
344 if (HasRGBA || (*compStr && IsRGBA(*compStr))) {
345 if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion < 220) {
346 const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr;
347 S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector)
348 << StringRef(DiagBegin, 1)
349 << S.getLangOpts().OpenCLVersion << SourceRange(CompLoc);
350 }
351 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000352 } else {
353 if (HexSwizzle) compStr++;
354 while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) {
355 if (HasIndex[Idx]) HasRepeated = true;
356 HasIndex[Idx] = true;
357 compStr++;
358 }
359 }
360
361 if (!HalvingSwizzle && *compStr) {
362 // We didn't get to the end of the string. This means the component names
363 // didn't come from the same set *or* we encountered an illegal name.
364 S.Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000365 << StringRef(compStr, 1) << SourceRange(CompLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000366 return QualType();
367 }
368
369 // Ensure no component accessor exceeds the width of the vector type it
370 // operates on.
371 if (!HalvingSwizzle) {
372 compStr = CompName->getNameStart();
373
374 if (HexSwizzle)
375 compStr++;
376
377 while (*compStr) {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000378 if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000379 S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
380 << baseType << SourceRange(CompLoc);
381 return QualType();
382 }
383 }
384 }
385
Bruno Cardoso Lopes9e575182017-10-17 17:54:57 +0000386 // OpenCL mode requires swizzle length to be in accordance with accepted
387 // sizes. Clang however supports arbitrary lengths for other languages.
388 if (S.getLangOpts().OpenCL && !HalvingSwizzle) {
Egor Churaev392a5072017-03-21 13:20:57 +0000389 unsigned SwizzleLength = CompName->getLength();
390
391 if (HexSwizzle)
392 SwizzleLength--;
393
394 if (IsValidOpenCLComponentSwizzleLength(SwizzleLength) == false) {
395 S.Diag(OpLoc, diag::err_opencl_ext_vector_component_invalid_length)
396 << SwizzleLength << SourceRange(CompLoc);
397 return QualType();
398 }
399 }
400
Douglas Gregor5476205b2011-06-23 00:49:38 +0000401 // The component accessor looks fine - now we need to compute the actual type.
402 // The vector type is implied by the component accessor. For example,
403 // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
404 // vec4.s0 is a float, vec4.s23 is a vec3, etc.
405 // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
406 unsigned CompSize = HalvingSwizzle ? (vecType->getNumElements() + 1) / 2
407 : CompName->getLength();
408 if (HexSwizzle)
409 CompSize--;
410
411 if (CompSize == 1)
412 return vecType->getElementType();
413
414 if (HasRepeated) VK = VK_RValue;
415
416 QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize);
417 // Now look up the TypeDefDecl from the vector type. Without this,
418 // diagostics look bad. We want extended vector types to appear built-in.
Fangrui Song6907ce22018-07-30 19:24:48 +0000419 for (Sema::ExtVectorDeclsType::iterator
Axel Naumanndd433f02012-10-18 19:05:02 +0000420 I = S.ExtVectorDecls.begin(S.getExternalSource()),
Fangrui Song6907ce22018-07-30 19:24:48 +0000421 E = S.ExtVectorDecls.end();
Douglas Gregorb7098a32011-07-28 00:39:29 +0000422 I != E; ++I) {
423 if ((*I)->getUnderlyingType() == VT)
424 return S.Context.getTypedefType(*I);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000425 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000426
Douglas Gregor5476205b2011-06-23 00:49:38 +0000427 return VT; // should never get here (a typedef type should always be found).
428}
429
430static Decl *FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
431 IdentifierInfo *Member,
432 const Selector &Sel,
433 ASTContext &Context) {
434 if (Member)
Manman Ren5b786402016-01-28 18:49:28 +0000435 if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(
436 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000437 return PD;
438 if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
439 return OMD;
440
Aaron Ballman0f6e64d2014-03-13 22:58:06 +0000441 for (const auto *I : PDecl->protocols()) {
442 if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000443 Context))
444 return D;
445 }
Craig Topperc3ec1492014-05-26 06:22:03 +0000446 return nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000447}
448
449static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy,
450 IdentifierInfo *Member,
451 const Selector &Sel,
452 ASTContext &Context) {
453 // Check protocols on qualified interfaces.
Craig Topperc3ec1492014-05-26 06:22:03 +0000454 Decl *GDecl = nullptr;
Aaron Ballman83731462014-03-17 16:14:00 +0000455 for (const auto *I : QIdTy->quals()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000456 if (Member)
Manman Ren5b786402016-01-28 18:49:28 +0000457 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
458 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000459 GDecl = PD;
460 break;
461 }
462 // Also must look for a getter or setter name which uses property syntax.
Aaron Ballman83731462014-03-17 16:14:00 +0000463 if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000464 GDecl = OMD;
465 break;
466 }
467 }
468 if (!GDecl) {
Aaron Ballman83731462014-03-17 16:14:00 +0000469 for (const auto *I : QIdTy->quals()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000470 // Search in the protocol-qualifier list of current protocol.
Aaron Ballman83731462014-03-17 16:14:00 +0000471 GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000472 if (GDecl)
473 return GDecl;
474 }
475 }
476 return GDecl;
477}
478
479ExprResult
480Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
481 bool IsArrow, SourceLocation OpLoc,
482 const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000483 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000484 NamedDecl *FirstQualifierInScope,
485 const DeclarationNameInfo &NameInfo,
486 const TemplateArgumentListInfo *TemplateArgs) {
487 // Even in dependent contexts, try to diagnose base expressions with
488 // obviously wrong types, e.g.:
489 //
490 // T* t;
491 // t.f;
492 //
493 // In Obj-C++, however, the above expression is valid, since it could be
494 // accessing the 'f' property if T is an Obj-C interface. The extra check
495 // allows this, while still reporting an error if T is a struct pointer.
496 if (!IsArrow) {
497 const PointerType *PT = BaseType->getAs<PointerType>();
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000498 if (PT && (!getLangOpts().ObjC ||
Douglas Gregor5476205b2011-06-23 00:49:38 +0000499 PT->getPointeeType()->isRecordType())) {
500 assert(BaseExpr && "cannot happen with implicit member accesses");
Matt Beaumont-Gayd9f244af2012-04-21 01:12:48 +0000501 Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
Matt Beaumont-Gay025321b2012-04-21 02:13:04 +0000502 << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000503 return ExprError();
504 }
505 }
506
507 assert(BaseType->isDependentType() ||
508 NameInfo.getName().isDependentName() ||
509 isDependentScopeSpecifier(SS));
510
511 // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
512 // must have pointer type, and the accessed type is the pointee.
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000513 return CXXDependentScopeMemberExpr::Create(
514 Context, BaseExpr, BaseType, IsArrow, OpLoc,
515 SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
516 NameInfo, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000517}
518
519/// We know that the given qualified member reference points only to
520/// declarations which do not belong to the static type of the base
521/// expression. Diagnose the problem.
522static void DiagnoseQualifiedMemberReference(Sema &SemaRef,
523 Expr *BaseExpr,
524 QualType BaseType,
525 const CXXScopeSpec &SS,
526 NamedDecl *rep,
527 const DeclarationNameInfo &nameInfo) {
528 // If this is an implicit member access, use a different set of
529 // diagnostics.
530 if (!BaseExpr)
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000531 return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000532
533 SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated)
534 << SS.getRange() << rep << BaseType;
535}
536
537// Check whether the declarations we found through a nested-name
538// specifier in a member expression are actually members of the base
539// type. The restriction here is:
540//
541// C++ [expr.ref]p2:
542// ... In these cases, the id-expression shall name a
543// member of the class or of one of its base classes.
544//
545// So it's perfectly legitimate for the nested-name specifier to name
546// an unrelated class, and for us to find an overload set including
547// decls from classes which are not superclasses, as long as the decl
548// we actually pick through overload resolution is from a superclass.
549bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
550 QualType BaseType,
551 const CXXScopeSpec &SS,
552 const LookupResult &R) {
Richard Smithd80b2d52012-11-22 00:24:47 +0000553 CXXRecordDecl *BaseRecord =
554 cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType));
555 if (!BaseRecord) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000556 // We can't check this yet because the base type is still
557 // dependent.
558 assert(BaseType->isDependentType());
559 return false;
560 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000561
562 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
563 // If this is an implicit member reference and we find a
564 // non-instance member, it's not an error.
565 if (!BaseExpr && !(*I)->isCXXInstanceMember())
566 return false;
567
568 // Note that we use the DC of the decl, not the underlying decl.
569 DeclContext *DC = (*I)->getDeclContext();
570 while (DC->isTransparentContext())
571 DC = DC->getParent();
572
573 if (!DC->isRecord())
574 continue;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000575
Richard Smithd80b2d52012-11-22 00:24:47 +0000576 CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
577 if (BaseRecord->getCanonicalDecl() == MemberRecord ||
578 !BaseRecord->isProvablyNotDerivedFrom(MemberRecord))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000579 return false;
580 }
581
582 DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS,
583 R.getRepresentativeDecl(),
584 R.getLookupNameInfo());
585 return true;
586}
587
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000588namespace {
589
590// Callback to only accept typo corrections that are either a ValueDecl or a
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000591// FunctionTemplateDecl and are declared in the current record or, for a C++
592// classes, one of its base classes.
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000593class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000594public:
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000595 explicit RecordMemberExprValidatorCCC(const RecordType *RTy)
Kaelyn Takatae9e4ecf2014-11-11 23:00:40 +0000596 : Record(RTy->getDecl()) {
597 // Don't add bare keywords to the consumer since they will always fail
598 // validation by virtue of not being associated with any decls.
599 WantTypeSpecifiers = false;
600 WantExpressionKeywords = false;
601 WantCXXNamedCasts = false;
602 WantFunctionLikeCasts = false;
603 WantRemainingKeywords = false;
604 }
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000605
Craig Toppere14c0f82014-03-12 04:55:44 +0000606 bool ValidateCandidate(const TypoCorrection &candidate) override {
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000607 NamedDecl *ND = candidate.getCorrectionDecl();
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000608 // Don't accept candidates that cannot be member functions, constants,
609 // variables, or templates.
610 if (!ND || !(isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)))
611 return false;
612
613 // Accept candidates that occur in the current record.
614 if (Record->containsDecl(ND))
615 return true;
616
617 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) {
618 // Accept candidates that occur in any of the current class' base classes.
Aaron Ballman574705e2014-03-13 15:41:46 +0000619 for (const auto &BS : RD->bases()) {
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000620 if (const RecordType *BSTy =
621 dyn_cast_or_null<RecordType>(BS.getType().getTypePtrOrNull())) {
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000622 if (BSTy->getDecl()->containsDecl(ND))
623 return true;
624 }
625 }
626 }
627
628 return false;
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000629 }
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000630
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000631private:
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000632 const RecordDecl *const Record;
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000633};
634
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000635}
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000636
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000637static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000638 Expr *BaseExpr,
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000639 const RecordType *RTy,
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000640 SourceLocation OpLoc, bool IsArrow,
641 CXXScopeSpec &SS, bool HasTemplateArgs,
Richard Smith79810042018-05-11 02:43:08 +0000642 SourceLocation TemplateKWLoc,
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000643 TypoExpr *&TE) {
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000644 SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000645 RecordDecl *RDecl = RTy->getDecl();
Douglas Gregor3024f072012-04-16 07:05:22 +0000646 if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&
647 SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
Douglas Gregor7bfb2d02012-05-04 16:32:21 +0000648 diag::err_typecheck_incomplete_tag,
649 BaseRange))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000650 return true;
651
Richard Smith79810042018-05-11 02:43:08 +0000652 if (HasTemplateArgs || TemplateKWLoc.isValid()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000653 // LookupTemplateName doesn't expect these both to exist simultaneously.
654 QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0);
655
656 bool MOUS;
Richard Smith79810042018-05-11 02:43:08 +0000657 return SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS,
658 TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000659 }
660
661 DeclContext *DC = RDecl;
662 if (SS.isSet()) {
663 // If the member name was a qualified-id, look into the
664 // nested-name-specifier.
665 DC = SemaRef.computeDeclContext(SS, false);
666
667 if (SemaRef.RequireCompleteDeclContext(SS, DC)) {
668 SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag)
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000669 << SS.getRange() << DC;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000670 return true;
671 }
672
673 assert(DC && "Cannot handle non-computable dependent contexts in lookup");
674
675 if (!isa<TypeDecl>(DC)) {
676 SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_nonclass)
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000677 << DC << SS.getRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000678 return true;
679 }
680 }
681
682 // The record definition is complete, now look up the member.
Nikola Smiljanicfce370e2014-12-01 23:15:01 +0000683 SemaRef.LookupQualifiedName(R, DC, SS);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000684
685 if (!R.empty())
686 return false;
687
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000688 DeclarationName Typo = R.getLookupName();
689 SourceLocation TypoLoc = R.getNameLoc();
David Blaikiea8173ba2015-09-28 23:48:55 +0000690
691 struct QueryState {
692 Sema &SemaRef;
693 DeclarationNameInfo NameInfo;
694 Sema::LookupNameKind LookupKind;
695 Sema::RedeclarationKind Redecl;
696 };
697 QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
Richard Smithbecb92d2017-10-10 22:33:17 +0000698 R.redeclarationKind()};
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000699 TE = SemaRef.CorrectTypoDelayed(
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000700 R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
701 llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000702 [=, &SemaRef](const TypoCorrection &TC) {
703 if (TC) {
704 assert(!TC.isKeyword() &&
705 "Got a keyword as a correction for a member!");
706 bool DroppedSpecifier =
707 TC.WillReplaceSpecifier() &&
708 Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
709 SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
710 << Typo << DC << DroppedSpecifier
711 << SS.getRange());
712 } else {
713 SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange;
714 }
715 },
716 [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
David Blaikiea8173ba2015-09-28 23:48:55 +0000717 LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl);
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000718 R.clear(); // Ensure there's no decls lingering in the shared state.
719 R.suppressDiagnostics();
720 R.setLookupName(TC.getCorrection());
721 for (NamedDecl *ND : TC)
722 R.addDecl(ND);
723 R.resolveKind();
724 return SemaRef.BuildMemberReferenceExpr(
725 BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(),
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000726 nullptr, R, nullptr, nullptr);
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000727 },
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000728 Sema::CTK_ErrorRecovery, DC);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000729
730 return false;
731}
732
Richard Smitha0edd302014-05-31 00:18:32 +0000733static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
734 ExprResult &BaseExpr, bool &IsArrow,
735 SourceLocation OpLoc, CXXScopeSpec &SS,
Richard Smith79810042018-05-11 02:43:08 +0000736 Decl *ObjCImpDecl, bool HasTemplateArgs,
737 SourceLocation TemplateKWLoc);
Richard Smitha0edd302014-05-31 00:18:32 +0000738
Douglas Gregor5476205b2011-06-23 00:49:38 +0000739ExprResult
740Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
741 SourceLocation OpLoc, bool IsArrow,
742 CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000743 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000744 NamedDecl *FirstQualifierInScope,
745 const DeclarationNameInfo &NameInfo,
Richard Smitha0edd302014-05-31 00:18:32 +0000746 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000747 const Scope *S,
Richard Smitha0edd302014-05-31 00:18:32 +0000748 ActOnMemberAccessExtraArgs *ExtraArgs) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000749 if (BaseType->isDependentType() ||
750 (SS.isSet() && isDependentScopeSpecifier(SS)))
751 return ActOnDependentMemberExpr(Base, BaseType,
752 IsArrow, OpLoc,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000753 SS, TemplateKWLoc, FirstQualifierInScope,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000754 NameInfo, TemplateArgs);
755
756 LookupResult R(*this, NameInfo, LookupMemberName);
757
758 // Implicit member accesses.
759 if (!Base) {
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000760 TypoExpr *TE = nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000761 QualType RecordTy = BaseType;
762 if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
Richard Smithc08b6932018-04-27 02:00:13 +0000763 if (LookupMemberExprInRecord(
764 *this, R, nullptr, RecordTy->getAs<RecordType>(), OpLoc, IsArrow,
Richard Smith79810042018-05-11 02:43:08 +0000765 SS, TemplateArgs != nullptr, TemplateKWLoc, TE))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000766 return ExprError();
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000767 if (TE)
768 return TE;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000769
770 // Explicit member accesses.
771 } else {
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000772 ExprResult BaseResult = Base;
Richard Smithc08b6932018-04-27 02:00:13 +0000773 ExprResult Result =
774 LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS,
775 ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
Richard Smith79810042018-05-11 02:43:08 +0000776 TemplateArgs != nullptr, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000777
778 if (BaseResult.isInvalid())
779 return ExprError();
Nikola Smiljanic01a75982014-05-29 10:55:11 +0000780 Base = BaseResult.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000781
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000782 if (Result.isInvalid())
Douglas Gregor5476205b2011-06-23 00:49:38 +0000783 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000784
785 if (Result.get())
Benjamin Kramer62b95d82012-08-23 21:35:17 +0000786 return Result;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000787
788 // LookupMemberExpr can modify Base, and thus change BaseType
789 BaseType = Base->getType();
790 }
791
792 return BuildMemberReferenceExpr(Base, BaseType,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000793 OpLoc, IsArrow, SS, TemplateKWLoc,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000794 FirstQualifierInScope, R, TemplateArgs, S,
Richard Smitha0edd302014-05-31 00:18:32 +0000795 false, ExtraArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000796}
797
Douglas Gregor5476205b2011-06-23 00:49:38 +0000798ExprResult
799Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
800 SourceLocation loc,
801 IndirectFieldDecl *indirectField,
Eli Friedmancccd0642013-07-16 00:01:31 +0000802 DeclAccessPair foundDecl,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000803 Expr *baseObjectExpr,
804 SourceLocation opLoc) {
805 // First, build the expression that refers to the base object.
Eric Fiseliere099fc12018-04-08 05:12:55 +0000806
Douglas Gregor5476205b2011-06-23 00:49:38 +0000807 // Case 1: the base of the indirect field is not a field.
808 VarDecl *baseVariable = indirectField->getVarDecl();
809 CXXScopeSpec EmptySS;
810 if (baseVariable) {
811 assert(baseVariable->getType()->isRecordType());
Eric Fiseliere099fc12018-04-08 05:12:55 +0000812
Douglas Gregor5476205b2011-06-23 00:49:38 +0000813 // In principle we could have a member access expression that
814 // accesses an anonymous struct/union that's a static member of
815 // the base object's class. However, under the current standard,
816 // static data members cannot be anonymous structs or unions.
817 // Supporting this is as easy as building a MemberExpr here.
818 assert(!baseObjectExpr && "anonymous struct/union is static data member?");
Fangrui Song6907ce22018-07-30 19:24:48 +0000819
Douglas Gregor5476205b2011-06-23 00:49:38 +0000820 DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
Fangrui Song6907ce22018-07-30 19:24:48 +0000821
822 ExprResult result
Douglas Gregor5476205b2011-06-23 00:49:38 +0000823 = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
824 if (result.isInvalid()) return ExprError();
Eric Fiseliere099fc12018-04-08 05:12:55 +0000825
826 baseObjectExpr = result.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000827 }
Eric Fiseliere099fc12018-04-08 05:12:55 +0000828
829 assert((baseVariable || baseObjectExpr) &&
830 "referencing anonymous struct/union without a base variable or "
831 "expression");
832
Douglas Gregor5476205b2011-06-23 00:49:38 +0000833 // Build the implicit member references to the field of the
834 // anonymous struct/union.
835 Expr *result = baseObjectExpr;
836 IndirectFieldDecl::chain_iterator
837 FI = indirectField->chain_begin(), FEnd = indirectField->chain_end();
Eric Fiseliere099fc12018-04-08 05:12:55 +0000838
839 // Case 2: the base of the indirect field is a field and the user
840 // wrote a member expression.
Douglas Gregor5476205b2011-06-23 00:49:38 +0000841 if (!baseVariable) {
842 FieldDecl *field = cast<FieldDecl>(*FI);
Eric Fiseliere099fc12018-04-08 05:12:55 +0000843
844 bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType();
845
Douglas Gregor5476205b2011-06-23 00:49:38 +0000846 // Make a nameInfo that properly uses the anonymous name.
847 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000848
Eric Fiseliere099fc12018-04-08 05:12:55 +0000849 // Build the first member access in the chain with full information.
850 result =
851 BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(),
Eric Fiselier4b8c9912018-04-08 06:21:33 +0000852 SS, field, foundDecl, memberNameInfo)
Eric Fiseliere099fc12018-04-08 05:12:55 +0000853 .get();
Eli Friedmancccd0642013-07-16 00:01:31 +0000854 if (!result)
855 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000856 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000857
Douglas Gregor5476205b2011-06-23 00:49:38 +0000858 // In all cases, we should now skip the first declaration in the chain.
859 ++FI;
Fangrui Song6907ce22018-07-30 19:24:48 +0000860
Douglas Gregor5476205b2011-06-23 00:49:38 +0000861 while (FI != FEnd) {
862 FieldDecl *field = cast<FieldDecl>(*FI++);
Eli Friedmancccd0642013-07-16 00:01:31 +0000863
Douglas Gregor5476205b2011-06-23 00:49:38 +0000864 // FIXME: these are somewhat meaningless
865 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
Eli Friedmancccd0642013-07-16 00:01:31 +0000866 DeclAccessPair fakeFoundDecl =
867 DeclAccessPair::make(field, field->getAccess());
868
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000869 result =
Richard Smith7873de02016-08-11 22:25:46 +0000870 BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(),
871 (FI == FEnd ? SS : EmptySS), field,
872 fakeFoundDecl, memberNameInfo)
873 .get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000874 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000875
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000876 return result;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000877}
878
John McCall5e77d762013-04-16 07:28:30 +0000879static ExprResult
880BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
881 const CXXScopeSpec &SS,
882 MSPropertyDecl *PD,
883 const DeclarationNameInfo &NameInfo) {
884 // Property names are always simple identifiers and therefore never
885 // require any interesting additional storage.
886 return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
887 S.Context.PseudoObjectTy, VK_LValue,
888 SS.getWithLocInContext(S.Context),
889 NameInfo.getLoc());
890}
891
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000892/// Build a MemberExpr AST node.
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000893static MemberExpr *BuildMemberExpr(
894 Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow,
895 SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
896 ValueDecl *Member, DeclAccessPair FoundDecl,
897 const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK,
898 ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = nullptr) {
Richard Smith08b12f12011-10-27 22:11:44 +0000899 assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000900 MemberExpr *E = MemberExpr::Create(
901 C, Base, isArrow, OpLoc, SS.getWithLocInContext(C), TemplateKWLoc, Member,
902 FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK);
Eli Friedmanfa0df832012-02-02 03:46:19 +0000903 SemaRef.MarkMemberReferenced(E);
904 return E;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000905}
906
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000907/// Determine if the given scope is within a function-try-block handler.
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000908static bool IsInFnTryBlockHandler(const Scope *S) {
909 // Walk the scope stack until finding a FnTryCatchScope, or leave the
910 // function scope. If a FnTryCatchScope is found, check whether the TryScope
911 // flag is set. If it is not, it's a function-try-block handler.
912 for (; S != S->getFnParent(); S = S->getParent()) {
913 if (S->getFlags() & Scope::FnTryCatchScope)
914 return (S->getFlags() & Scope::TryScope) != Scope::TryScope;
915 }
916 return false;
917}
918
Faisal Valie7f8fb92016-02-22 02:24:29 +0000919static VarDecl *
920getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl,
921 const TemplateArgumentListInfo *TemplateArgs,
922 const DeclarationNameInfo &MemberNameInfo,
923 SourceLocation TemplateKWLoc) {
Faisal Valie7f8fb92016-02-22 02:24:29 +0000924 if (!TemplateArgs) {
Richard Smithecad88d2018-04-26 01:08:00 +0000925 S.diagnoseMissingTemplateArguments(TemplateName(VarTempl),
926 MemberNameInfo.getBeginLoc());
Faisal Valie7f8fb92016-02-22 02:24:29 +0000927 return nullptr;
928 }
Richard Smithecad88d2018-04-26 01:08:00 +0000929
Faisal Valie7f8fb92016-02-22 02:24:29 +0000930 DeclResult VDecl = S.CheckVarTemplateId(
931 VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs);
932 if (VDecl.isInvalid())
933 return nullptr;
934 VarDecl *Var = cast<VarDecl>(VDecl.get());
935 if (!Var->getTemplateSpecializationKind())
936 Var->setTemplateSpecializationKind(TSK_ImplicitInstantiation,
937 MemberNameInfo.getLoc());
938 return Var;
939}
940
Douglas Gregor5476205b2011-06-23 00:49:38 +0000941ExprResult
942Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
943 SourceLocation OpLoc, bool IsArrow,
944 const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000945 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000946 NamedDecl *FirstQualifierInScope,
947 LookupResult &R,
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000948 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000949 const Scope *S,
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000950 bool SuppressQualifierCheck,
951 ActOnMemberAccessExtraArgs *ExtraArgs) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000952 QualType BaseType = BaseExprType;
953 if (IsArrow) {
954 assert(BaseType->isPointerType());
John McCall526ab472011-10-25 17:37:35 +0000955 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000956 }
957 R.setBaseObjectType(BaseType);
Richard Smith4baaa5a2016-12-03 01:14:32 +0000958
959 // C++1z [expr.ref]p2:
960 // For the first option (dot) the first expression shall be a glvalue [...]
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000961 if (!IsArrow && BaseExpr && BaseExpr->isRValue()) {
Richard Smith4baaa5a2016-12-03 01:14:32 +0000962 ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
963 if (Converted.isInvalid())
964 return ExprError();
965 BaseExpr = Converted.get();
966 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000967
968
Douglas Gregor5476205b2011-06-23 00:49:38 +0000969 const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
970 DeclarationName MemberName = MemberNameInfo.getName();
971 SourceLocation MemberLoc = MemberNameInfo.getLoc();
972
973 if (R.isAmbiguous())
974 return ExprError();
975
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000976 // [except.handle]p10: Referring to any non-static member or base class of an
977 // object in the handler for a function-try-block of a constructor or
978 // destructor for that object results in undefined behavior.
979 const auto *FD = getCurFunctionDecl();
980 if (S && BaseExpr && FD &&
981 (isa<CXXDestructorDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
982 isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts()) &&
983 IsInFnTryBlockHandler(S))
984 Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr)
985 << isa<CXXDestructorDecl>(FD);
986
Douglas Gregor5476205b2011-06-23 00:49:38 +0000987 if (R.empty()) {
988 // Rederive where we looked up.
989 DeclContext *DC = (SS.isSet()
990 ? computeDeclContext(SS, false)
991 : BaseType->getAs<RecordType>()->getDecl());
992
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000993 if (ExtraArgs) {
994 ExprResult RetryExpr;
995 if (!IsArrow && BaseExpr) {
Kaelyn Uhraind4ea98a2012-05-01 01:17:53 +0000996 SFINAETrap Trap(*this, true);
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000997 ParsedType ObjectType;
998 bool MayBePseudoDestructor = false;
999 RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr,
1000 OpLoc, tok::arrow, ObjectType,
1001 MayBePseudoDestructor);
1002 if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) {
1003 CXXScopeSpec TempSS(SS);
1004 RetryExpr = ActOnMemberAccessExpr(
1005 ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS,
David Majnemerced8bdf2015-02-25 17:36:15 +00001006 TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl);
Kaelyn Uhrain76e07342012-04-25 19:49:54 +00001007 }
1008 if (Trap.hasErrorOccurred())
1009 RetryExpr = ExprError();
1010 }
1011 if (RetryExpr.isUsable()) {
1012 Diag(OpLoc, diag::err_no_member_overloaded_arrow)
1013 << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->");
1014 return RetryExpr;
1015 }
1016 }
1017
Douglas Gregor5476205b2011-06-23 00:49:38 +00001018 Diag(R.getNameLoc(), diag::err_no_member)
1019 << MemberName << DC
1020 << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
1021 return ExprError();
1022 }
1023
1024 // Diagnose lookups that find only declarations from a non-base
1025 // type. This is possible for either qualified lookups (which may
1026 // have been qualified with an unrelated type) or implicit member
1027 // expressions (which were found with unqualified lookup and thus
1028 // may have come from an enclosing scope). Note that it's okay for
1029 // lookup to find declarations from a non-base type as long as those
1030 // aren't the ones picked by overload resolution.
1031 if ((SS.isSet() || !BaseExpr ||
1032 (isa<CXXThisExpr>(BaseExpr) &&
1033 cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
1034 !SuppressQualifierCheck &&
1035 CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
1036 return ExprError();
Fangrui Song6907ce22018-07-30 19:24:48 +00001037
Douglas Gregor5476205b2011-06-23 00:49:38 +00001038 // Construct an unresolved result if we in fact got an unresolved
1039 // result.
1040 if (R.isOverloadedResult() || R.isUnresolvableResult()) {
1041 // Suppress any lookup-related diagnostics; we'll do these when we
1042 // pick a member.
1043 R.suppressDiagnostics();
1044
1045 UnresolvedMemberExpr *MemExpr
1046 = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(),
1047 BaseExpr, BaseExprType,
1048 IsArrow, OpLoc,
1049 SS.getWithLocInContext(Context),
Abramo Bagnara7945c982012-01-27 09:46:47 +00001050 TemplateKWLoc, MemberNameInfo,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001051 TemplateArgs, R.begin(), R.end());
1052
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001053 return MemExpr;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001054 }
1055
1056 assert(R.isSingleResult());
1057 DeclAccessPair FoundDecl = R.begin().getPair();
1058 NamedDecl *MemberDecl = R.getFoundDecl();
1059
1060 // FIXME: diagnose the presence of template arguments now.
1061
1062 // If the decl being referenced had an error, return an error for this
1063 // sub-expr without emitting another error, in order to avoid cascading
1064 // error cases.
1065 if (MemberDecl->isInvalidDecl())
1066 return ExprError();
1067
1068 // Handle the implicit-member-access case.
1069 if (!BaseExpr) {
1070 // If this is not an instance member, convert to a non-member access.
Faisal Valie7f8fb92016-02-22 02:24:29 +00001071 if (!MemberDecl->isCXXInstanceMember()) {
1072 // If this is a variable template, get the instantiated variable
1073 // declaration corresponding to the supplied template arguments
1074 // (while emitting diagnostics as necessary) that will be referenced
1075 // by this expression.
Faisal Vali640dc752016-02-25 05:09:30 +00001076 assert((!TemplateArgs || isa<VarTemplateDecl>(MemberDecl)) &&
1077 "How did we get template arguments here sans a variable template");
Faisal Valie7f8fb92016-02-22 02:24:29 +00001078 if (isa<VarTemplateDecl>(MemberDecl)) {
1079 MemberDecl = getVarTemplateSpecialization(
1080 *this, cast<VarTemplateDecl>(MemberDecl), TemplateArgs,
1081 R.getLookupNameInfo(), TemplateKWLoc);
1082 if (!MemberDecl)
1083 return ExprError();
1084 }
Faisal Vali640dc752016-02-25 05:09:30 +00001085 return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl,
1086 FoundDecl, TemplateArgs);
Faisal Valie7f8fb92016-02-22 02:24:29 +00001087 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001088 SourceLocation Loc = R.getNameLoc();
1089 if (SS.getRange().isValid())
1090 Loc = SS.getRange().getBegin();
Eli Friedman73a04092012-01-07 04:59:52 +00001091 CheckCXXThisCapture(Loc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001092 BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
1093 }
1094
Douglas Gregor5476205b2011-06-23 00:49:38 +00001095 // Check the use of this member.
Davide Italianof179e362015-07-22 00:30:58 +00001096 if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001097 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001098
Douglas Gregor5476205b2011-06-23 00:49:38 +00001099 if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
Richard Smith7873de02016-08-11 22:25:46 +00001100 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
1101 MemberNameInfo);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001102
John McCall5e77d762013-04-16 07:28:30 +00001103 if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
1104 return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
1105 MemberNameInfo);
1106
Douglas Gregor5476205b2011-06-23 00:49:38 +00001107 if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
1108 // We may have found a field within an anonymous union or struct
1109 // (C++ [class.union]).
1110 return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
Eli Friedmancccd0642013-07-16 00:01:31 +00001111 FoundDecl, BaseExpr,
1112 OpLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001113
1114 if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001115 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1116 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001117 Var->getType().getNonReferenceType(), VK_LValue,
1118 OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001119 }
1120
1121 if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
1122 ExprValueKind valueKind;
1123 QualType type;
1124 if (MemberFn->isInstance()) {
1125 valueKind = VK_RValue;
1126 type = Context.BoundMemberTy;
1127 } else {
1128 valueKind = VK_LValue;
1129 type = MemberFn->getType();
1130 }
1131
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001132 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1133 TemplateKWLoc, MemberFn, FoundDecl, MemberNameInfo,
1134 type, valueKind, OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001135 }
1136 assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
1137
1138 if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001139 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1140 TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
1141 Enum->getType(), VK_RValue, OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001142 }
Faisal Valie7f8fb92016-02-22 02:24:29 +00001143 if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
1144 if (VarDecl *Var = getVarTemplateSpecialization(
1145 *this, VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc))
1146 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1147 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
1148 Var->getType().getNonReferenceType(), VK_LValue,
1149 OK_Ordinary);
1150 return ExprError();
1151 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001152
Douglas Gregor5476205b2011-06-23 00:49:38 +00001153 // We found something that we didn't expect. Complain.
1154 if (isa<TypeDecl>(MemberDecl))
1155 Diag(MemberLoc, diag::err_typecheck_member_reference_type)
1156 << MemberName << BaseType << int(IsArrow);
1157 else
1158 Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
1159 << MemberName << BaseType << int(IsArrow);
1160
1161 Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
1162 << MemberName;
1163 R.suppressDiagnostics();
1164 return ExprError();
1165}
1166
1167/// Given that normal member access failed on the given expression,
1168/// and given that the expression's type involves builtin-id or
1169/// builtin-Class, decide whether substituting in the redefinition
1170/// types would be profitable. The redefinition type is whatever
1171/// this translation unit tried to typedef to id/Class; we store
1172/// it to the side and then re-use it in places like this.
1173static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base) {
1174 const ObjCObjectPointerType *opty
1175 = base.get()->getType()->getAs<ObjCObjectPointerType>();
1176 if (!opty) return false;
1177
1178 const ObjCObjectType *ty = opty->getObjectType();
1179
1180 QualType redef;
1181 if (ty->isObjCId()) {
Douglas Gregor97673472011-08-11 20:58:55 +00001182 redef = S.Context.getObjCIdRedefinitionType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001183 } else if (ty->isObjCClass()) {
Douglas Gregor97673472011-08-11 20:58:55 +00001184 redef = S.Context.getObjCClassRedefinitionType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001185 } else {
1186 return false;
1187 }
1188
1189 // Do the substitution as long as the redefinition type isn't just a
1190 // possibly-qualified pointer to builtin-id or builtin-Class again.
1191 opty = redef->getAs<ObjCObjectPointerType>();
Richard Trieuf20d9052012-10-12 17:48:40 +00001192 if (opty && !opty->getObjectType()->getInterface())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001193 return false;
1194
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001195 base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001196 return true;
1197}
1198
John McCall50a2c2c2011-10-11 23:14:30 +00001199static bool isRecordType(QualType T) {
1200 return T->isRecordType();
1201}
1202static bool isPointerToRecordType(QualType T) {
1203 if (const PointerType *PT = T->getAs<PointerType>())
1204 return PT->getPointeeType()->isRecordType();
1205 return false;
1206}
1207
Richard Smithcab9a7d2011-10-26 19:06:56 +00001208/// Perform conversions on the LHS of a member access expression.
1209ExprResult
1210Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
Eli Friedman9a766c42012-01-13 02:20:01 +00001211 if (IsArrow && !Base->getType()->isFunctionType())
1212 return DefaultFunctionArrayLvalueConversion(Base);
Richard Smithcab9a7d2011-10-26 19:06:56 +00001213
Eli Friedman9a766c42012-01-13 02:20:01 +00001214 return CheckPlaceholderExpr(Base);
Richard Smithcab9a7d2011-10-26 19:06:56 +00001215}
1216
Douglas Gregor5476205b2011-06-23 00:49:38 +00001217/// Look up the given member of the given non-type-dependent
1218/// expression. This can return in one of two ways:
1219/// * If it returns a sentinel null-but-valid result, the caller will
1220/// assume that lookup was performed and the results written into
1221/// the provided structure. It will take over from there.
1222/// * Otherwise, the returned expression will be produced in place of
1223/// an ordinary member expression.
1224///
1225/// The ObjCImpDecl bit is a gross hack that will need to be properly
1226/// fixed for ObjC++.
Richard Smitha0edd302014-05-31 00:18:32 +00001227static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
1228 ExprResult &BaseExpr, bool &IsArrow,
1229 SourceLocation OpLoc, CXXScopeSpec &SS,
Richard Smith79810042018-05-11 02:43:08 +00001230 Decl *ObjCImpDecl, bool HasTemplateArgs,
1231 SourceLocation TemplateKWLoc) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001232 assert(BaseExpr.get() && "no base expression");
1233
1234 // Perform default conversions.
Richard Smitha0edd302014-05-31 00:18:32 +00001235 BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
John McCall50a2c2c2011-10-11 23:14:30 +00001236 if (BaseExpr.isInvalid())
1237 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001238
Douglas Gregor5476205b2011-06-23 00:49:38 +00001239 QualType BaseType = BaseExpr.get()->getType();
1240 assert(!BaseType->isDependentType());
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->isRecordType()) {
1256 // Recover from arrow accesses to records, e.g.:
1257 // struct MyRecord foo;
1258 // foo->bar
1259 // This is actually well-formed in C++ if MyRecord has an
1260 // overloaded operator->, but that should have been dealt with
Kaelyn Uhrain0c51de42013-07-31 17:38:24 +00001261 // by now--or a diagnostic message already issued if a problem
1262 // was encountered while looking for the overloaded operator->.
Richard Smitha0edd302014-05-31 00:18:32 +00001263 if (!S.getLangOpts().CPlusPlus) {
1264 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
Kaelyn Uhrainbd6ddaa2013-10-31 20:32:56 +00001265 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1266 << FixItHint::CreateReplacement(OpLoc, ".");
1267 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001268 IsArrow = false;
Eli Friedman9a766c42012-01-13 02:20:01 +00001269 } else if (BaseType->isFunctionType()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001270 goto fail;
1271 } else {
Richard Smitha0edd302014-05-31 00:18:32 +00001272 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001273 << BaseType << BaseExpr.get()->getSourceRange();
1274 return ExprError();
1275 }
1276 }
1277
1278 // Handle field access to simple records.
1279 if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
Kaelyn Takatafe408a72014-10-27 18:07:46 +00001280 TypoExpr *TE = nullptr;
Richard Smith79810042018-05-11 02:43:08 +00001281 if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, OpLoc, IsArrow, SS,
1282 HasTemplateArgs, TemplateKWLoc, TE))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001283 return ExprError();
1284
1285 // Returning valid-but-null is how we indicate to the caller that
Kaelyn Takatafe408a72014-10-27 18:07:46 +00001286 // the lookup result was filled in. If typo correction was attempted and
1287 // failed, the lookup result will have been cleared--that combined with the
1288 // valid-but-null ExprResult will trigger the appropriate diagnostics.
1289 return ExprResult(TE);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001290 }
1291
1292 // Handle ivar access to Objective-C objects.
1293 if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
Douglas Gregorbcc95392011-10-10 16:09:49 +00001294 if (!SS.isEmpty() && !SS.isInvalid()) {
Richard Smitha0edd302014-05-31 00:18:32 +00001295 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
Douglas Gregor12340e52011-10-09 23:22:49 +00001296 << 1 << SS.getScopeRep()
1297 << FixItHint::CreateRemoval(SS.getRange());
1298 SS.clear();
1299 }
Richard Smitha0edd302014-05-31 00:18:32 +00001300
Douglas Gregor5476205b2011-06-23 00:49:38 +00001301 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1302
1303 // There are three cases for the base type:
1304 // - builtin id (qualified or unqualified)
1305 // - builtin Class (qualified or unqualified)
1306 // - an interface
1307 ObjCInterfaceDecl *IDecl = OTy->getInterface();
1308 if (!IDecl) {
Richard Smitha0edd302014-05-31 00:18:32 +00001309 if (S.getLangOpts().ObjCAutoRefCount &&
Douglas Gregor5476205b2011-06-23 00:49:38 +00001310 (OTy->isObjCId() || OTy->isObjCClass()))
1311 goto fail;
1312 // There's an implicit 'isa' ivar on all objects.
1313 // But we only actually find it this way on objects of type 'id',
Eric Christopherae6b9d22012-08-16 23:50:37 +00001314 // apparently.
Fariborz Jahanian84510742013-03-27 21:19:25 +00001315 if (OTy->isObjCId() && Member->isStr("isa"))
Richard Smitha0edd302014-05-31 00:18:32 +00001316 return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1317 OpLoc, S.Context.getObjCClassType());
1318 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1319 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001320 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001321 goto fail;
1322 }
Richard Smitha0edd302014-05-31 00:18:32 +00001323
1324 if (S.RequireCompleteType(OpLoc, BaseType,
1325 diag::err_typecheck_incomplete_tag,
1326 BaseExpr.get()))
Douglas Gregor5dbf4eb2012-01-02 17:18:37 +00001327 return ExprError();
Craig Topperc3ec1492014-05-26 06:22:03 +00001328
1329 ObjCInterfaceDecl *ClassDeclared = nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001330 ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1331
1332 if (!IV) {
1333 // Attempt to correct for typos in ivar names.
Kaelyn Takata89c881b2014-10-27 18:07:29 +00001334 auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>();
1335 Validator->IsObjCIvarLookup = IsArrow;
Richard Smitha0edd302014-05-31 00:18:32 +00001336 if (TypoCorrection Corrected = S.CorrectTypo(
1337 R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
Kaelyn Takata89c881b2014-10-27 18:07:29 +00001338 std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) {
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +00001339 IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
Richard Smitha0edd302014-05-31 00:18:32 +00001340 S.diagnoseTypo(
1341 Corrected,
1342 S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1343 << IDecl->getDeclName() << MemberName);
Richard Smithf9b15102013-08-17 00:46:16 +00001344
Ted Kremenek679b4782012-03-17 00:53:39 +00001345 // Figure out the class that declares the ivar.
1346 assert(!ClassDeclared);
Saleem Abdulrasool765a2192016-11-17 17:10:54 +00001347
Ted Kremenek679b4782012-03-17 00:53:39 +00001348 Decl *D = cast<Decl>(IV->getDeclContext());
Saleem Abdulrasool765a2192016-11-17 17:10:54 +00001349 if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1350 D = Category->getClassInterface();
1351
1352 if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1353 ClassDeclared = Implementation->getClassInterface();
1354 else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1355 ClassDeclared = Interface;
1356
1357 assert(ClassDeclared && "cannot query interface");
Douglas Gregor5476205b2011-06-23 00:49:38 +00001358 } else {
Manman Ren5b786402016-01-28 18:49:28 +00001359 if (IsArrow &&
1360 IDecl->FindPropertyDeclaration(
1361 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
Richard Smitha0edd302014-05-31 00:18:32 +00001362 S.Diag(MemberLoc, diag::err_property_found_suggest)
1363 << Member << BaseExpr.get()->getType()
1364 << FixItHint::CreateReplacement(OpLoc, ".");
Fariborz Jahanianc297cd82011-06-28 00:00:52 +00001365 return ExprError();
1366 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001367
Richard Smitha0edd302014-05-31 00:18:32 +00001368 S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1369 << IDecl->getDeclName() << MemberName
1370 << BaseExpr.get()->getSourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001371 return ExprError();
1372 }
1373 }
Richard Smitha0edd302014-05-31 00:18:32 +00001374
Ted Kremenek679b4782012-03-17 00:53:39 +00001375 assert(ClassDeclared);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001376
1377 // If the decl being referenced had an error, return an error for this
1378 // sub-expr without emitting another error, in order to avoid cascading
1379 // error cases.
1380 if (IV->isInvalidDecl())
1381 return ExprError();
1382
1383 // Check whether we can reference this field.
Richard Smitha0edd302014-05-31 00:18:32 +00001384 if (S.DiagnoseUseOfDecl(IV, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001385 return ExprError();
1386 if (IV->getAccessControl() != ObjCIvarDecl::Public &&
1387 IV->getAccessControl() != ObjCIvarDecl::Package) {
Craig Topperc3ec1492014-05-26 06:22:03 +00001388 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
Richard Smitha0edd302014-05-31 00:18:32 +00001389 if (ObjCMethodDecl *MD = S.getCurMethodDecl())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001390 ClassOfMethodDecl = MD->getClassInterface();
Richard Smitha0edd302014-05-31 00:18:32 +00001391 else if (ObjCImpDecl && S.getCurFunctionDecl()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001392 // Case of a c-function declared inside an objc implementation.
1393 // FIXME: For a c-style function nested inside an objc implementation
1394 // class, there is no implementation context available, so we pass
1395 // down the context as argument to this routine. Ideally, this context
1396 // need be passed down in the AST node and somehow calculated from the
1397 // AST for a function decl.
1398 if (ObjCImplementationDecl *IMPD =
1399 dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1400 ClassOfMethodDecl = IMPD->getClassInterface();
1401 else if (ObjCCategoryImplDecl* CatImplClass =
1402 dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1403 ClassOfMethodDecl = CatImplClass->getClassInterface();
1404 }
Richard Smitha0edd302014-05-31 00:18:32 +00001405 if (!S.getLangOpts().DebuggerSupport) {
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001406 if (IV->getAccessControl() == ObjCIvarDecl::Private) {
1407 if (!declaresSameEntity(ClassDeclared, IDecl) ||
1408 !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
Richard Smithf8812672016-12-02 22:38:31 +00001409 S.Diag(MemberLoc, diag::err_private_ivar_access)
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001410 << IV->getDeclName();
1411 } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1412 // @protected
Richard Smithf8812672016-12-02 22:38:31 +00001413 S.Diag(MemberLoc, diag::err_protected_ivar_access)
Richard Smitha0edd302014-05-31 00:18:32 +00001414 << IV->getDeclName();
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001415 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001416 }
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001417 bool warn = true;
Brian Kelleycafd9122017-03-29 17:55:11 +00001418 if (S.getLangOpts().ObjCWeak) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001419 Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1420 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1421 if (UO->getOpcode() == UO_Deref)
1422 BaseExp = UO->getSubExpr()->IgnoreParenCasts();
Fangrui Song6907ce22018-07-30 19:24:48 +00001423
Douglas Gregor5476205b2011-06-23 00:49:38 +00001424 if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001425 if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
Richard Smithf8812672016-12-02 22:38:31 +00001426 S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001427 warn = false;
1428 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001429 }
Fariborz Jahaniana5063a62012-08-08 16:41:04 +00001430 if (warn) {
Richard Smitha0edd302014-05-31 00:18:32 +00001431 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001432 ObjCMethodFamily MF = MD->getMethodFamily();
Fangrui Song6907ce22018-07-30 19:24:48 +00001433 warn = (MF != OMF_init && MF != OMF_dealloc &&
Fariborz Jahaniana934a022013-02-14 19:07:19 +00001434 MF != OMF_finalize &&
Richard Smitha0edd302014-05-31 00:18:32 +00001435 !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001436 }
1437 if (warn)
Richard Smitha0edd302014-05-31 00:18:32 +00001438 S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001439 }
Jordan Rose657b5f42012-09-28 22:21:35 +00001440
Richard Smitha0edd302014-05-31 00:18:32 +00001441 ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
Douglas Gregore83b9562015-07-07 03:57:53 +00001442 IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1443 IsArrow);
Jordan Rose657b5f42012-09-28 22:21:35 +00001444
Brian Kelleycafd9122017-03-29 17:55:11 +00001445 if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
Reid Kleckner04f9bca2018-03-07 22:48:35 +00001446 if (!S.isUnevaluatedContext() &&
1447 !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1448 S.getCurFunction()->recordUseOfWeak(Result);
Jordan Rose657b5f42012-09-28 22:21:35 +00001449 }
1450
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001451 return Result;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001452 }
1453
1454 // Objective-C property access.
1455 const ObjCObjectPointerType *OPT;
1456 if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
Douglas Gregorbcc95392011-10-10 16:09:49 +00001457 if (!SS.isEmpty() && !SS.isInvalid()) {
Richard Smitha0edd302014-05-31 00:18:32 +00001458 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1459 << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
Douglas Gregor12340e52011-10-09 23:22:49 +00001460 SS.clear();
1461 }
1462
Douglas Gregor5476205b2011-06-23 00:49:38 +00001463 // This actually uses the base as an r-value.
Richard Smitha0edd302014-05-31 00:18:32 +00001464 BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001465 if (BaseExpr.isInvalid())
1466 return ExprError();
1467
Richard Smitha0edd302014-05-31 00:18:32 +00001468 assert(S.Context.hasSameUnqualifiedType(BaseType,
1469 BaseExpr.get()->getType()));
Douglas Gregor5476205b2011-06-23 00:49:38 +00001470
1471 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1472
1473 const ObjCObjectType *OT = OPT->getObjectType();
1474
1475 // id, with and without qualifiers.
1476 if (OT->isObjCId()) {
1477 // Check protocols on qualified interfaces.
Richard Smitha0edd302014-05-31 00:18:32 +00001478 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
1479 if (Decl *PMDecl =
1480 FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001481 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1482 // Check the use of this declaration
Richard Smitha0edd302014-05-31 00:18:32 +00001483 if (S.DiagnoseUseOfDecl(PD, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001484 return ExprError();
1485
Richard Smitha0edd302014-05-31 00:18:32 +00001486 return new (S.Context)
1487 ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001488 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001489 }
1490
1491 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001492 Selector SetterSel =
Richard Smitha0edd302014-05-31 00:18:32 +00001493 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1494 S.PP.getSelectorTable(),
Adrian Prantla4ce9062013-06-07 22:29:12 +00001495 Member);
Craig Topperc3ec1492014-05-26 06:22:03 +00001496 ObjCMethodDecl *SMD = nullptr;
1497 if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
Richard Smitha0edd302014-05-31 00:18:32 +00001498 /*Property id*/ nullptr,
1499 SetterSel, S.Context))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001500 SMD = dyn_cast<ObjCMethodDecl>(SDecl);
Richard Smitha0edd302014-05-31 00:18:32 +00001501
1502 return new (S.Context)
1503 ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001504 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001505 }
1506 }
1507 // Use of id.member can only be for a property reference. Do not
1508 // use the 'id' redefinition in this case.
Richard Smitha0edd302014-05-31 00:18:32 +00001509 if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1510 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001511 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001512
Richard Smitha0edd302014-05-31 00:18:32 +00001513 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001514 << MemberName << BaseType);
1515 }
1516
1517 // 'Class', unqualified only.
1518 if (OT->isObjCClass()) {
1519 // Only works in a method declaration (??!).
Richard Smitha0edd302014-05-31 00:18:32 +00001520 ObjCMethodDecl *MD = S.getCurMethodDecl();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001521 if (!MD) {
Richard Smitha0edd302014-05-31 00:18:32 +00001522 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1523 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001524 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001525
1526 goto fail;
1527 }
1528
1529 // Also must look for a getter name which uses property syntax.
Richard Smitha0edd302014-05-31 00:18:32 +00001530 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001531 ObjCInterfaceDecl *IFace = MD->getClassInterface();
Shoaib Meenaiadf5a322018-03-27 18:58:28 +00001532 if (!IFace)
1533 goto fail;
1534
Douglas Gregor5476205b2011-06-23 00:49:38 +00001535 ObjCMethodDecl *Getter;
1536 if ((Getter = IFace->lookupClassMethod(Sel))) {
1537 // Check the use of this method.
Richard Smitha0edd302014-05-31 00:18:32 +00001538 if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001539 return ExprError();
1540 } else
1541 Getter = IFace->lookupPrivateMethod(Sel, false);
1542 // If we found a getter then this may be a valid dot-reference, we
1543 // will look for the matching setter, in case it is needed.
1544 Selector SetterSel =
Richard Smitha0edd302014-05-31 00:18:32 +00001545 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1546 S.PP.getSelectorTable(),
Adrian Prantla4ce9062013-06-07 22:29:12 +00001547 Member);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001548 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1549 if (!Setter) {
1550 // If this reference is in an @implementation, also check for 'private'
1551 // methods.
1552 Setter = IFace->lookupPrivateMethod(SetterSel, false);
1553 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001554
Richard Smitha0edd302014-05-31 00:18:32 +00001555 if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001556 return ExprError();
1557
1558 if (Getter || Setter) {
Richard Smitha0edd302014-05-31 00:18:32 +00001559 return new (S.Context) ObjCPropertyRefExpr(
1560 Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1561 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001562 }
1563
Richard Smitha0edd302014-05-31 00:18:32 +00001564 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1565 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001566 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001567
Richard Smitha0edd302014-05-31 00:18:32 +00001568 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001569 << MemberName << BaseType);
1570 }
1571
1572 // Normal property access.
Richard Smitha0edd302014-05-31 00:18:32 +00001573 return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
1574 MemberLoc, SourceLocation(), QualType(),
1575 false);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001576 }
1577
1578 // Handle 'field access' to vectors, such as 'V.xx'.
1579 if (BaseType->isExtVectorType()) {
1580 // FIXME: this expr should store IsArrow.
1581 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
Fariborz Jahanian220d08d2015-04-06 16:56:39 +00001582 ExprValueKind VK;
1583 if (IsArrow)
1584 VK = VK_LValue;
1585 else {
1586 if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(BaseExpr.get()))
1587 VK = POE->getSyntacticForm()->getValueKind();
1588 else
1589 VK = BaseExpr.get()->getValueKind();
1590 }
Andrew V. Tischenko425f7b42018-02-09 09:30:42 +00001591
Richard Smitha0edd302014-05-31 00:18:32 +00001592 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001593 Member, MemberLoc);
1594 if (ret.isNull())
1595 return ExprError();
Andrew V. Tischenko425f7b42018-02-09 09:30:42 +00001596 Qualifiers BaseQ =
1597 S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers();
1598 ret = S.Context.getQualifiedType(ret, BaseQ);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001599
Richard Smitha0edd302014-05-31 00:18:32 +00001600 return new (S.Context)
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001601 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001602 }
1603
1604 // Adjust builtin-sel to the appropriate redefinition type if that's
1605 // not just a pointer to builtin-sel again.
Richard Smitha0edd302014-05-31 00:18:32 +00001606 if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
1607 !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
1608 BaseExpr = S.ImpCastExprToType(
1609 BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1610 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001611 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001612 }
1613
1614 // Failure cases.
1615 fail:
1616
1617 // Recover from dot accesses to pointers, e.g.:
1618 // type *foo;
1619 // foo.bar
1620 // This is actually well-formed in two cases:
1621 // - 'type' is an Objective C type
1622 // - 'bar' is a pseudo-destructor name which happens to refer to
1623 // the appropriate pointer type
1624 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1625 if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
1626 MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
Richard Smitha0edd302014-05-31 00:18:32 +00001627 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1628 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
Douglas Gregor5476205b2011-06-23 00:49:38 +00001629 << FixItHint::CreateReplacement(OpLoc, "->");
1630
1631 // Recurse as an -> access.
1632 IsArrow = true;
Richard Smitha0edd302014-05-31 00:18:32 +00001633 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001634 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001635 }
1636 }
1637
1638 // If the user is trying to apply -> or . to a function name, it's probably
1639 // because they forgot parentheses to call that function.
Richard Smitha0edd302014-05-31 00:18:32 +00001640 if (S.tryToRecoverWithCall(
1641 BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1642 /*complain*/ false,
1643 IsArrow ? &isPointerToRecordType : &isRecordType)) {
John McCall50a2c2c2011-10-11 23:14:30 +00001644 if (BaseExpr.isInvalid())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001645 return ExprError();
Richard Smitha0edd302014-05-31 00:18:32 +00001646 BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1647 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Richard Smith79810042018-05-11 02:43:08 +00001648 ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001649 }
1650
Richard Smitha0edd302014-05-31 00:18:32 +00001651 S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
Matt Beaumont-Gay025321b2012-04-21 02:13:04 +00001652 << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001653
1654 return ExprError();
1655}
1656
1657/// The main callback when the parser finds something like
1658/// expression . [nested-name-specifier] identifier
1659/// expression -> [nested-name-specifier] identifier
1660/// where 'identifier' encompasses a fairly broad spectrum of
1661/// possibilities, including destructor and operator references.
1662///
1663/// \param OpKind either tok::arrow or tok::period
James Dennett2a4d13c2012-06-15 07:13:21 +00001664/// \param ObjCImpDecl the current Objective-C \@implementation
1665/// decl; this is an ugly hack around the fact that Objective-C
1666/// \@implementations aren't properly put in the context chain
Douglas Gregor5476205b2011-06-23 00:49:38 +00001667ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
1668 SourceLocation OpLoc,
1669 tok::TokenKind OpKind,
1670 CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001671 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001672 UnqualifiedId &Id,
David Majnemerced8bdf2015-02-25 17:36:15 +00001673 Decl *ObjCImpDecl) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001674 if (SS.isSet() && SS.isInvalid())
1675 return ExprError();
1676
1677 // Warn about the explicit constructor calls Microsoft extension.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001678 if (getLangOpts().MicrosoftExt &&
Faisal Vali2ab8c152017-12-30 04:15:27 +00001679 Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001680 Diag(Id.getSourceRange().getBegin(),
1681 diag::ext_ms_explicit_constructor_call);
1682
1683 TemplateArgumentListInfo TemplateArgsBuffer;
1684
1685 // Decompose the name into its component parts.
1686 DeclarationNameInfo NameInfo;
1687 const TemplateArgumentListInfo *TemplateArgs;
1688 DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1689 NameInfo, TemplateArgs);
1690
1691 DeclarationName Name = NameInfo.getName();
1692 bool IsArrow = (OpKind == tok::arrow);
1693
1694 NamedDecl *FirstQualifierInScope
Craig Topperc3ec1492014-05-26 06:22:03 +00001695 = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
Douglas Gregor5476205b2011-06-23 00:49:38 +00001696
1697 // This is a postfix expression, so get rid of ParenListExprs.
1698 ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
1699 if (Result.isInvalid()) return ExprError();
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001700 Base = Result.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001701
1702 if (Base->getType()->isDependentType() || Name.isDependentName() ||
1703 isDependentScopeSpecifier(SS)) {
Richard Smitha0edd302014-05-31 00:18:32 +00001704 return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
1705 TemplateKWLoc, FirstQualifierInScope,
1706 NameInfo, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001707 }
1708
David Majnemerced8bdf2015-02-25 17:36:15 +00001709 ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
Leonard Chanad7ac962018-12-06 01:05:54 +00001710 ExprResult Res = BuildMemberReferenceExpr(
1711 Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc,
1712 FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs);
1713
1714 if (!Res.isInvalid() && isa<MemberExpr>(Res.get()))
1715 CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get()));
1716
1717 return Res;
1718}
1719
1720void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
1721 QualType ResultTy = E->getType();
1722
1723 // Do not warn on member accesses to arrays since this returns an array
1724 // lvalue and does not actually dereference memory.
1725 if (isa<ArrayType>(ResultTy))
1726 return;
1727
1728 if (E->isArrow()) {
1729 if (const auto *Ptr = dyn_cast<PointerType>(
1730 E->getBase()->getType().getDesugaredType(Context))) {
1731 if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
1732 ExprEvalContexts.back().PossibleDerefs.insert(E);
1733 }
1734 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001735}
1736
Richard Smith7873de02016-08-11 22:25:46 +00001737ExprResult
1738Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1739 SourceLocation OpLoc, const CXXScopeSpec &SS,
1740 FieldDecl *Field, DeclAccessPair FoundDecl,
1741 const DeclarationNameInfo &MemberNameInfo) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001742 // x.a is an l-value if 'a' has a reference type. Otherwise:
1743 // x.a is an l-value/x-value/pr-value if the base is (and note
1744 // that *x is always an l-value), except that if the base isn't
1745 // an ordinary object then we must have an rvalue.
1746 ExprValueKind VK = VK_LValue;
1747 ExprObjectKind OK = OK_Ordinary;
1748 if (!IsArrow) {
1749 if (BaseExpr->getObjectKind() == OK_Ordinary)
1750 VK = BaseExpr->getValueKind();
1751 else
1752 VK = VK_RValue;
1753 }
1754 if (VK != VK_RValue && Field->isBitField())
1755 OK = OK_BitField;
Fangrui Song6907ce22018-07-30 19:24:48 +00001756
Douglas Gregor5476205b2011-06-23 00:49:38 +00001757 // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1758 QualType MemberType = Field->getType();
1759 if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1760 MemberType = Ref->getPointeeType();
1761 VK = VK_LValue;
1762 } else {
1763 QualType BaseType = BaseExpr->getType();
1764 if (IsArrow) BaseType = BaseType->getAs<PointerType>()->getPointeeType();
Matt Arsenault376f7202013-02-26 21:16:00 +00001765
Douglas Gregor5476205b2011-06-23 00:49:38 +00001766 Qualifiers BaseQuals = BaseType.getQualifiers();
Matt Arsenault376f7202013-02-26 21:16:00 +00001767
Douglas Gregor5476205b2011-06-23 00:49:38 +00001768 // GC attributes are never picked up by members.
1769 BaseQuals.removeObjCGCAttr();
Matt Arsenault376f7202013-02-26 21:16:00 +00001770
Douglas Gregor5476205b2011-06-23 00:49:38 +00001771 // CVR attributes from the base are picked up by members,
1772 // except that 'mutable' members don't pick up 'const'.
1773 if (Field->isMutable()) BaseQuals.removeConst();
Matt Arsenault376f7202013-02-26 21:16:00 +00001774
Richard Smith7873de02016-08-11 22:25:46 +00001775 Qualifiers MemberQuals =
1776 Context.getCanonicalType(MemberType).getQualifiers();
Matt Arsenault376f7202013-02-26 21:16:00 +00001777
Douglas Gregor5476205b2011-06-23 00:49:38 +00001778 assert(!MemberQuals.hasAddressSpace());
Matt Arsenault376f7202013-02-26 21:16:00 +00001779
Douglas Gregor5476205b2011-06-23 00:49:38 +00001780 Qualifiers Combined = BaseQuals + MemberQuals;
1781 if (Combined != MemberQuals)
Richard Smith7873de02016-08-11 22:25:46 +00001782 MemberType = Context.getQualifiedType(MemberType, Combined);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001783 }
Matt Arsenault376f7202013-02-26 21:16:00 +00001784
Richard Smitha31174e2017-11-01 04:52:12 +00001785 auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
1786 if (!(CurMethod && CurMethod->isDefaulted()))
1787 UnusedPrivateFields.remove(Field);
Daniel Jasper0baec5492012-06-06 08:32:04 +00001788
Richard Smith7873de02016-08-11 22:25:46 +00001789 ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
1790 FoundDecl, Field);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001791 if (Base.isInvalid())
1792 return ExprError();
Alexey Bataev90c228f2016-02-08 09:29:13 +00001793
1794 // Build a reference to a private copy for non-static data members in
1795 // non-static member functions, privatized by OpenMP constructs.
Richard Smith7873de02016-08-11 22:25:46 +00001796 if (getLangOpts().OpenMP && IsArrow &&
1797 !CurContext->isDependentContext() &&
Alexey Bataev90c228f2016-02-08 09:29:13 +00001798 isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
Alexey Bataeve3727102018-04-18 15:57:46 +00001799 if (auto *PrivateCopy = isOpenMPCapturedDecl(Field)) {
Alexey Bataev4d4624c2017-07-20 16:47:47 +00001800 return getOpenMPCapturedExpr(PrivateCopy, VK, OK,
1801 MemberNameInfo.getLoc());
1802 }
Alexey Bataev90c228f2016-02-08 09:29:13 +00001803 }
Alexey Bataevd0c03ca2017-07-11 19:43:28 +00001804
1805 return BuildMemberExpr(*this, Context, Base.get(), IsArrow, OpLoc, SS,
1806 /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1807 MemberNameInfo, MemberType, VK, OK);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001808}
1809
1810/// Builds an implicit member access expression. The current context
1811/// is known to be an instance method, and the given unqualified lookup
1812/// set is known to contain only instance members, at least one of which
1813/// is from an appropriate type.
1814ExprResult
1815Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001816 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001817 LookupResult &R,
1818 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001819 bool IsKnownInstance, const Scope *S) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001820 assert(!R.empty() && !R.isAmbiguous());
Fangrui Song6907ce22018-07-30 19:24:48 +00001821
Douglas Gregor5476205b2011-06-23 00:49:38 +00001822 SourceLocation loc = R.getNameLoc();
Richard Smith59d26d22014-01-17 22:29:43 +00001823
Douglas Gregor5476205b2011-06-23 00:49:38 +00001824 // If this is known to be an instance access, go ahead and build an
1825 // implicit 'this' expression now.
1826 // 'this' expression now.
Douglas Gregor09deffa2011-10-18 16:47:30 +00001827 QualType ThisTy = getCurrentThisType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001828 assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
Craig Topperc3ec1492014-05-26 06:22:03 +00001829
1830 Expr *baseExpr = nullptr; // null signifies implicit access
Douglas Gregor5476205b2011-06-23 00:49:38 +00001831 if (IsKnownInstance) {
1832 SourceLocation Loc = R.getNameLoc();
1833 if (SS.getRange().isValid())
1834 Loc = SS.getRange().getBegin();
Eli Friedman73a04092012-01-07 04:59:52 +00001835 CheckCXXThisCapture(Loc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001836 baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true);
1837 }
Craig Topperc3ec1492014-05-26 06:22:03 +00001838
Douglas Gregor5476205b2011-06-23 00:49:38 +00001839 return BuildMemberReferenceExpr(baseExpr, ThisTy,
1840 /*OpLoc*/ SourceLocation(),
1841 /*IsArrow*/ true,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001842 SS, TemplateKWLoc,
Craig Topperc3ec1492014-05-26 06:22:03 +00001843 /*FirstQualifierInScope*/ nullptr,
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001844 R, TemplateArgs, S);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001845}