blob: f08bdc5e9c814721af548e565cd11fc3289a7ce8 [file] [log] [blame]
Douglas Gregor5476205b2011-06-23 00:49:38 +00001//===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements semantic analysis member access expressions.
11//
12//===----------------------------------------------------------------------===//
Kaelyn Takatafe408a72014-10-27 18:07:46 +000013#include "clang/Sema/Overload.h"
Faisal Valia17d19f2013-11-07 05:17:06 +000014#include "clang/AST/ASTLambda.h"
Douglas Gregor5476205b2011-06-23 00:49:38 +000015#include "clang/AST/DeclCXX.h"
16#include "clang/AST/DeclObjC.h"
17#include "clang/AST/DeclTemplate.h"
18#include "clang/AST/ExprCXX.h"
19#include "clang/AST/ExprObjC.h"
20#include "clang/Lex/Preprocessor.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "clang/Sema/Lookup.h"
22#include "clang/Sema/Scope.h"
23#include "clang/Sema/ScopeInfo.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000024#include "clang/Sema/SemaInternal.h"
Douglas Gregor5476205b2011-06-23 00:49:38 +000025
26using namespace clang;
27using namespace sema;
28
Richard Smithd80b2d52012-11-22 00:24:47 +000029typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> BaseSet;
Richard Smithd80b2d52012-11-22 00:24:47 +000030
Douglas Gregor5476205b2011-06-23 00:49:38 +000031/// Determines if the given class is provably not derived from all of
32/// the prospective base classes.
Richard Smithd80b2d52012-11-22 00:24:47 +000033static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record,
34 const BaseSet &Bases) {
Benjamin Kramer6e4f6e12015-07-25 15:07:25 +000035 auto BaseIsNotInSet = [&Bases](const CXXRecordDecl *Base) {
36 return !Bases.count(Base->getCanonicalDecl());
37 };
38 return BaseIsNotInSet(Record) && Record->forallBases(BaseIsNotInSet);
Douglas Gregor5476205b2011-06-23 00:49:38 +000039}
40
41enum IMAKind {
42 /// The reference is definitely not an instance member access.
43 IMA_Static,
44
45 /// The reference may be an implicit instance member access.
46 IMA_Mixed,
47
Eli Friedman7bda7f72012-01-18 03:53:45 +000048 /// The reference may be to an instance member, but it might be invalid if
Douglas Gregor5476205b2011-06-23 00:49:38 +000049 /// so, because the context is not an instance method.
50 IMA_Mixed_StaticContext,
51
52 /// The reference may be to an instance member, but it is invalid if
53 /// so, because the context is from an unrelated class.
54 IMA_Mixed_Unrelated,
55
56 /// The reference is definitely an implicit instance member access.
57 IMA_Instance,
58
59 /// The reference may be to an unresolved using declaration.
60 IMA_Unresolved,
61
John McCallf413f5e2013-05-03 00:10:13 +000062 /// The reference is a contextually-permitted abstract member reference.
63 IMA_Abstract,
64
Douglas Gregor5476205b2011-06-23 00:49:38 +000065 /// The reference may be to an unresolved using declaration and the
66 /// context is not an instance method.
67 IMA_Unresolved_StaticContext,
68
Eli Friedman456f0182012-01-20 01:26:23 +000069 // The reference refers to a field which is not a member of the containing
70 // class, which is allowed because we're in C++11 mode and the context is
71 // unevaluated.
72 IMA_Field_Uneval_Context,
Eli Friedman7bda7f72012-01-18 03:53:45 +000073
Douglas Gregor5476205b2011-06-23 00:49:38 +000074 /// All possible referrents are instance members and the current
75 /// context is not an instance method.
76 IMA_Error_StaticContext,
77
78 /// All possible referrents are instance members of an unrelated
79 /// class.
80 IMA_Error_Unrelated
81};
82
83/// The given lookup names class member(s) and is not being used for
84/// an address-of-member expression. Classify the type of access
85/// according to whether it's possible that this reference names an
Eli Friedman7bda7f72012-01-18 03:53:45 +000086/// instance member. This is best-effort in dependent contexts; it is okay to
Douglas Gregor5476205b2011-06-23 00:49:38 +000087/// conservatively answer "yes", in which case some errors will simply
88/// not be caught until template-instantiation.
89static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
Douglas Gregor5476205b2011-06-23 00:49:38 +000090 const LookupResult &R) {
91 assert(!R.empty() && (*R.begin())->isCXXClassMember());
92
93 DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
94
Douglas Gregor3024f072012-04-16 07:05:22 +000095 bool isStaticContext = SemaRef.CXXThisTypeOverride.isNull() &&
96 (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic());
Douglas Gregor5476205b2011-06-23 00:49:38 +000097
98 if (R.isUnresolvableResult())
99 return isStaticContext ? IMA_Unresolved_StaticContext : IMA_Unresolved;
100
101 // Collect all the declaring classes of instance members we find.
102 bool hasNonInstance = false;
Eli Friedman7bda7f72012-01-18 03:53:45 +0000103 bool isField = false;
Richard Smithd80b2d52012-11-22 00:24:47 +0000104 BaseSet Classes;
Reid Kleckner077fe122015-10-20 18:12:08 +0000105 for (NamedDecl *D : R) {
106 // Look through any using decls.
107 D = D->getUnderlyingDecl();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000108
109 if (D->isCXXInstanceMember()) {
Benjamin Kramera008d3a2015-04-10 11:37:55 +0000110 isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
111 isa<IndirectFieldDecl>(D);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000112
113 CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
114 Classes.insert(R->getCanonicalDecl());
Reid Kleckner077fe122015-10-20 18:12:08 +0000115 } else
Douglas Gregor5476205b2011-06-23 00:49:38 +0000116 hasNonInstance = true;
117 }
118
119 // If we didn't find any instance members, it can't be an implicit
120 // member reference.
121 if (Classes.empty())
122 return IMA_Static;
John McCallf413f5e2013-05-03 00:10:13 +0000123
124 // C++11 [expr.prim.general]p12:
125 // An id-expression that denotes a non-static data member or non-static
126 // member function of a class can only be used:
127 // (...)
128 // - if that id-expression denotes a non-static data member and it
129 // appears in an unevaluated operand.
130 //
131 // This rule is specific to C++11. However, we also permit this form
132 // in unevaluated inline assembly operands, like the operand to a SIZE.
133 IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false'
134 assert(!AbstractInstanceResult);
135 switch (SemaRef.ExprEvalContexts.back().Context) {
136 case Sema::Unevaluated:
Richard Smithd6a15082017-01-07 00:48:55 +0000137 case Sema::UnevaluatedList:
John McCallf413f5e2013-05-03 00:10:13 +0000138 if (isField && SemaRef.getLangOpts().CPlusPlus11)
139 AbstractInstanceResult = IMA_Field_Uneval_Context;
140 break;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000141
John McCallf413f5e2013-05-03 00:10:13 +0000142 case Sema::UnevaluatedAbstract:
143 AbstractInstanceResult = IMA_Abstract;
144 break;
145
Richard Smithb130fe72016-06-23 19:16:49 +0000146 case Sema::DiscardedStatement:
John McCallf413f5e2013-05-03 00:10:13 +0000147 case Sema::ConstantEvaluated:
148 case Sema::PotentiallyEvaluated:
149 case Sema::PotentiallyEvaluatedIfUsed:
150 break;
Richard Smitheae99682012-02-25 10:04:07 +0000151 }
152
Douglas Gregor5476205b2011-06-23 00:49:38 +0000153 // If the current context is not an instance method, it can't be
154 // an implicit member reference.
155 if (isStaticContext) {
156 if (hasNonInstance)
Richard Smitheae99682012-02-25 10:04:07 +0000157 return IMA_Mixed_StaticContext;
158
John McCallf413f5e2013-05-03 00:10:13 +0000159 return AbstractInstanceResult ? AbstractInstanceResult
160 : IMA_Error_StaticContext;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000161 }
162
163 CXXRecordDecl *contextClass;
164 if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
165 contextClass = MD->getParent()->getCanonicalDecl();
166 else
167 contextClass = cast<CXXRecordDecl>(DC);
168
169 // [class.mfct.non-static]p3:
170 // ...is used in the body of a non-static member function of class X,
171 // if name lookup (3.4.1) resolves the name in the id-expression to a
172 // non-static non-type member of some class C [...]
173 // ...if C is not X or a base class of X, the class member access expression
174 // is ill-formed.
175 if (R.getNamingClass() &&
DeLesley Hutchins5b330db2012-02-25 00:11:55 +0000176 contextClass->getCanonicalDecl() !=
Richard Smithd80b2d52012-11-22 00:24:47 +0000177 R.getNamingClass()->getCanonicalDecl()) {
178 // If the naming class is not the current context, this was a qualified
179 // member name lookup, and it's sufficient to check that we have the naming
180 // class as a base class.
181 Classes.clear();
Richard Smithb2c5f962012-11-22 00:40:54 +0000182 Classes.insert(R.getNamingClass()->getCanonicalDecl());
Richard Smithd80b2d52012-11-22 00:24:47 +0000183 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000184
185 // If we can prove that the current context is unrelated to all the
186 // declaring classes, it can't be an implicit member reference (in
187 // which case it's an error if any of those members are selected).
Richard Smithd80b2d52012-11-22 00:24:47 +0000188 if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
Richard Smith2a986112012-02-25 10:20:59 +0000189 return hasNonInstance ? IMA_Mixed_Unrelated :
John McCallf413f5e2013-05-03 00:10:13 +0000190 AbstractInstanceResult ? AbstractInstanceResult :
191 IMA_Error_Unrelated;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000192
193 return (hasNonInstance ? IMA_Mixed : IMA_Instance);
194}
195
196/// Diagnose a reference to a field with no object available.
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000197static void diagnoseInstanceReference(Sema &SemaRef,
198 const CXXScopeSpec &SS,
199 NamedDecl *Rep,
200 const DeclarationNameInfo &nameInfo) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000201 SourceLocation Loc = nameInfo.getLoc();
202 SourceRange Range(Loc);
203 if (SS.isSet()) Range.setBegin(SS.getRange().getBegin());
Eli Friedman7bda7f72012-01-18 03:53:45 +0000204
Reid Klecknerae628962014-12-18 00:42:51 +0000205 // Look through using shadow decls and aliases.
206 Rep = Rep->getUnderlyingDecl();
207
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000208 DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();
Richard Smithfa0a1f52012-04-05 01:13:04 +0000209 CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);
Craig Topperc3ec1492014-05-26 06:22:03 +0000210 CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000211 CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext());
212
213 bool InStaticMethod = Method && Method->isStatic();
214 bool IsField = isa<FieldDecl>(Rep) || isa<IndirectFieldDecl>(Rep);
215
216 if (IsField && InStaticMethod)
217 // "invalid use of member 'x' in static member function"
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000218 SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method)
Richard Smithfa0a1f52012-04-05 01:13:04 +0000219 << Range << nameInfo.getName();
220 else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod &&
221 !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass))
222 // Unqualified lookup in a non-static member function found a member of an
223 // enclosing class.
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000224 SemaRef.Diag(Loc, diag::err_nested_non_static_member_use)
225 << IsField << RepClass << nameInfo.getName() << ContextClass << Range;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000226 else if (IsField)
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000227 SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use)
228 << nameInfo.getName() << Range;
Richard Smithfa0a1f52012-04-05 01:13:04 +0000229 else
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000230 SemaRef.Diag(Loc, diag::err_member_call_without_object)
231 << Range;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000232}
233
234/// Builds an expression which might be an implicit member expression.
235ExprResult
236Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000237 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000238 LookupResult &R,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000239 const TemplateArgumentListInfo *TemplateArgs,
240 const Scope *S) {
Reid Klecknerae628962014-12-18 00:42:51 +0000241 switch (ClassifyImplicitMemberAccess(*this, R)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000242 case IMA_Instance:
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000243 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000244
245 case IMA_Mixed:
246 case IMA_Mixed_Unrelated:
247 case IMA_Unresolved:
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000248 return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
249 S);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000250
Richard Smith2a986112012-02-25 10:20:59 +0000251 case IMA_Field_Uneval_Context:
252 Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
253 << R.getLookupNameInfo().getName();
254 // Fall through.
Douglas Gregor5476205b2011-06-23 00:49:38 +0000255 case IMA_Static:
John McCallf413f5e2013-05-03 00:10:13 +0000256 case IMA_Abstract:
Douglas Gregor5476205b2011-06-23 00:49:38 +0000257 case IMA_Mixed_StaticContext:
258 case IMA_Unresolved_StaticContext:
Abramo Bagnara65f7c3d2012-02-06 14:31:00 +0000259 if (TemplateArgs || TemplateKWLoc.isValid())
260 return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000261 return BuildDeclarationNameExpr(SS, R, false);
262
263 case IMA_Error_StaticContext:
264 case IMA_Error_Unrelated:
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000265 diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(),
Douglas Gregor5476205b2011-06-23 00:49:38 +0000266 R.getLookupNameInfo());
267 return ExprError();
268 }
269
270 llvm_unreachable("unexpected instance member access kind");
Douglas Gregor5476205b2011-06-23 00:49:38 +0000271}
272
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000273/// Determine whether input char is from rgba component set.
274static bool
275IsRGBA(char c) {
276 switch (c) {
277 case 'r':
278 case 'g':
279 case 'b':
280 case 'a':
281 return true;
282 default:
283 return false;
284 }
285}
286
Douglas Gregor5476205b2011-06-23 00:49:38 +0000287/// Check an ext-vector component access expression.
288///
289/// VK should be set in advance to the value kind of the base
290/// expression.
291static QualType
292CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
293 SourceLocation OpLoc, const IdentifierInfo *CompName,
294 SourceLocation CompLoc) {
295 // FIXME: Share logic with ExtVectorElementExpr::containsDuplicateElements,
296 // see FIXME there.
297 //
298 // FIXME: This logic can be greatly simplified by splitting it along
299 // halving/not halving and reworking the component checking.
300 const ExtVectorType *vecType = baseType->getAs<ExtVectorType>();
301
302 // The vector accessor can't exceed the number of elements.
303 const char *compStr = CompName->getNameStart();
304
305 // This flag determines whether or not the component is one of the four
306 // special names that indicate a subset of exactly half the elements are
307 // to be selected.
308 bool HalvingSwizzle = false;
309
310 // This flag determines whether or not CompName has an 's' char prefix,
311 // indicating that it is a string of hex values to be used as vector indices.
Fariborz Jahanian275542a2014-04-03 19:43:01 +0000312 bool HexSwizzle = (*compStr == 's' || *compStr == 'S') && compStr[1];
Douglas Gregor5476205b2011-06-23 00:49:38 +0000313
314 bool HasRepeated = false;
315 bool HasIndex[16] = {};
316
317 int Idx;
318
319 // Check that we've found one of the special components, or that the component
320 // names must come from the same set.
321 if (!strcmp(compStr, "hi") || !strcmp(compStr, "lo") ||
322 !strcmp(compStr, "even") || !strcmp(compStr, "odd")) {
323 HalvingSwizzle = true;
324 } else if (!HexSwizzle &&
325 (Idx = vecType->getPointAccessorIdx(*compStr)) != -1) {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000326 bool HasRGBA = IsRGBA(*compStr);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000327 do {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000328 // Ensure that xyzw and rgba components don't intermingle.
329 if (HasRGBA != IsRGBA(*compStr))
330 break;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000331 if (HasIndex[Idx]) HasRepeated = true;
332 HasIndex[Idx] = true;
333 compStr++;
334 } while (*compStr && (Idx = vecType->getPointAccessorIdx(*compStr)) != -1);
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000335
336 // Emit a warning if an rgba selector is used earlier than OpenCL 2.2
337 if (HasRGBA || (*compStr && IsRGBA(*compStr))) {
338 if (S.getLangOpts().OpenCL && S.getLangOpts().OpenCLVersion < 220) {
339 const char *DiagBegin = HasRGBA ? CompName->getNameStart() : compStr;
340 S.Diag(OpLoc, diag::ext_opencl_ext_vector_type_rgba_selector)
341 << StringRef(DiagBegin, 1)
342 << S.getLangOpts().OpenCLVersion << SourceRange(CompLoc);
343 }
344 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000345 } else {
346 if (HexSwizzle) compStr++;
347 while ((Idx = vecType->getNumericAccessorIdx(*compStr)) != -1) {
348 if (HasIndex[Idx]) HasRepeated = true;
349 HasIndex[Idx] = true;
350 compStr++;
351 }
352 }
353
354 if (!HalvingSwizzle && *compStr) {
355 // We didn't get to the end of the string. This means the component names
356 // didn't come from the same set *or* we encountered an illegal name.
357 S.Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000358 << StringRef(compStr, 1) << SourceRange(CompLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000359 return QualType();
360 }
361
362 // Ensure no component accessor exceeds the width of the vector type it
363 // operates on.
364 if (!HalvingSwizzle) {
365 compStr = CompName->getNameStart();
366
367 if (HexSwizzle)
368 compStr++;
369
370 while (*compStr) {
Pirama Arumuga Nainar98eaa622016-07-22 18:49:43 +0000371 if (!vecType->isAccessorWithinNumElements(*compStr++, HexSwizzle)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000372 S.Diag(OpLoc, diag::err_ext_vector_component_exceeds_length)
373 << baseType << SourceRange(CompLoc);
374 return QualType();
375 }
376 }
377 }
378
379 // The component accessor looks fine - now we need to compute the actual type.
380 // The vector type is implied by the component accessor. For example,
381 // vec4.b is a float, vec4.xy is a vec2, vec4.rgb is a vec3, etc.
382 // vec4.s0 is a float, vec4.s23 is a vec3, etc.
383 // vec4.hi, vec4.lo, vec4.e, and vec4.o all return vec2.
384 unsigned CompSize = HalvingSwizzle ? (vecType->getNumElements() + 1) / 2
385 : CompName->getLength();
386 if (HexSwizzle)
387 CompSize--;
388
389 if (CompSize == 1)
390 return vecType->getElementType();
391
392 if (HasRepeated) VK = VK_RValue;
393
394 QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize);
395 // Now look up the TypeDefDecl from the vector type. Without this,
396 // diagostics look bad. We want extended vector types to appear built-in.
Douglas Gregorb7098a32011-07-28 00:39:29 +0000397 for (Sema::ExtVectorDeclsType::iterator
Axel Naumanndd433f02012-10-18 19:05:02 +0000398 I = S.ExtVectorDecls.begin(S.getExternalSource()),
Douglas Gregorb7098a32011-07-28 00:39:29 +0000399 E = S.ExtVectorDecls.end();
400 I != E; ++I) {
401 if ((*I)->getUnderlyingType() == VT)
402 return S.Context.getTypedefType(*I);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000403 }
Douglas Gregorb7098a32011-07-28 00:39:29 +0000404
Douglas Gregor5476205b2011-06-23 00:49:38 +0000405 return VT; // should never get here (a typedef type should always be found).
406}
407
408static Decl *FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
409 IdentifierInfo *Member,
410 const Selector &Sel,
411 ASTContext &Context) {
412 if (Member)
Manman Ren5b786402016-01-28 18:49:28 +0000413 if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(
414 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000415 return PD;
416 if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
417 return OMD;
418
Aaron Ballman0f6e64d2014-03-13 22:58:06 +0000419 for (const auto *I : PDecl->protocols()) {
420 if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000421 Context))
422 return D;
423 }
Craig Topperc3ec1492014-05-26 06:22:03 +0000424 return nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000425}
426
427static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy,
428 IdentifierInfo *Member,
429 const Selector &Sel,
430 ASTContext &Context) {
431 // Check protocols on qualified interfaces.
Craig Topperc3ec1492014-05-26 06:22:03 +0000432 Decl *GDecl = nullptr;
Aaron Ballman83731462014-03-17 16:14:00 +0000433 for (const auto *I : QIdTy->quals()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000434 if (Member)
Manman Ren5b786402016-01-28 18:49:28 +0000435 if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(
436 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000437 GDecl = PD;
438 break;
439 }
440 // Also must look for a getter or setter name which uses property syntax.
Aaron Ballman83731462014-03-17 16:14:00 +0000441 if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000442 GDecl = OMD;
443 break;
444 }
445 }
446 if (!GDecl) {
Aaron Ballman83731462014-03-17 16:14:00 +0000447 for (const auto *I : QIdTy->quals()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000448 // Search in the protocol-qualifier list of current protocol.
Aaron Ballman83731462014-03-17 16:14:00 +0000449 GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000450 if (GDecl)
451 return GDecl;
452 }
453 }
454 return GDecl;
455}
456
457ExprResult
458Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
459 bool IsArrow, SourceLocation OpLoc,
460 const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000461 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000462 NamedDecl *FirstQualifierInScope,
463 const DeclarationNameInfo &NameInfo,
464 const TemplateArgumentListInfo *TemplateArgs) {
465 // Even in dependent contexts, try to diagnose base expressions with
466 // obviously wrong types, e.g.:
467 //
468 // T* t;
469 // t.f;
470 //
471 // In Obj-C++, however, the above expression is valid, since it could be
472 // accessing the 'f' property if T is an Obj-C interface. The extra check
473 // allows this, while still reporting an error if T is a struct pointer.
474 if (!IsArrow) {
475 const PointerType *PT = BaseType->getAs<PointerType>();
David Blaikiebbafb8a2012-03-11 07:00:24 +0000476 if (PT && (!getLangOpts().ObjC1 ||
Douglas Gregor5476205b2011-06-23 00:49:38 +0000477 PT->getPointeeType()->isRecordType())) {
478 assert(BaseExpr && "cannot happen with implicit member accesses");
Matt Beaumont-Gayd9f244af2012-04-21 01:12:48 +0000479 Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
Matt Beaumont-Gay025321b2012-04-21 02:13:04 +0000480 << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000481 return ExprError();
482 }
483 }
484
485 assert(BaseType->isDependentType() ||
486 NameInfo.getName().isDependentName() ||
487 isDependentScopeSpecifier(SS));
488
489 // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
490 // must have pointer type, and the accessed type is the pointee.
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000491 return CXXDependentScopeMemberExpr::Create(
492 Context, BaseExpr, BaseType, IsArrow, OpLoc,
493 SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
494 NameInfo, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000495}
496
497/// We know that the given qualified member reference points only to
498/// declarations which do not belong to the static type of the base
499/// expression. Diagnose the problem.
500static void DiagnoseQualifiedMemberReference(Sema &SemaRef,
501 Expr *BaseExpr,
502 QualType BaseType,
503 const CXXScopeSpec &SS,
504 NamedDecl *rep,
505 const DeclarationNameInfo &nameInfo) {
506 // If this is an implicit member access, use a different set of
507 // diagnostics.
508 if (!BaseExpr)
Reid Kleckner7d3a2f02015-10-20 00:31:42 +0000509 return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000510
511 SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated)
512 << SS.getRange() << rep << BaseType;
513}
514
515// Check whether the declarations we found through a nested-name
516// specifier in a member expression are actually members of the base
517// type. The restriction here is:
518//
519// C++ [expr.ref]p2:
520// ... In these cases, the id-expression shall name a
521// member of the class or of one of its base classes.
522//
523// So it's perfectly legitimate for the nested-name specifier to name
524// an unrelated class, and for us to find an overload set including
525// decls from classes which are not superclasses, as long as the decl
526// we actually pick through overload resolution is from a superclass.
527bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
528 QualType BaseType,
529 const CXXScopeSpec &SS,
530 const LookupResult &R) {
Richard Smithd80b2d52012-11-22 00:24:47 +0000531 CXXRecordDecl *BaseRecord =
532 cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType));
533 if (!BaseRecord) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000534 // We can't check this yet because the base type is still
535 // dependent.
536 assert(BaseType->isDependentType());
537 return false;
538 }
Douglas Gregor5476205b2011-06-23 00:49:38 +0000539
540 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
541 // If this is an implicit member reference and we find a
542 // non-instance member, it's not an error.
543 if (!BaseExpr && !(*I)->isCXXInstanceMember())
544 return false;
545
546 // Note that we use the DC of the decl, not the underlying decl.
547 DeclContext *DC = (*I)->getDeclContext();
548 while (DC->isTransparentContext())
549 DC = DC->getParent();
550
551 if (!DC->isRecord())
552 continue;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000553
Richard Smithd80b2d52012-11-22 00:24:47 +0000554 CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
555 if (BaseRecord->getCanonicalDecl() == MemberRecord ||
556 !BaseRecord->isProvablyNotDerivedFrom(MemberRecord))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000557 return false;
558 }
559
560 DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS,
561 R.getRepresentativeDecl(),
562 R.getLookupNameInfo());
563 return true;
564}
565
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000566namespace {
567
568// Callback to only accept typo corrections that are either a ValueDecl or a
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000569// FunctionTemplateDecl and are declared in the current record or, for a C++
570// classes, one of its base classes.
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000571class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000572public:
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000573 explicit RecordMemberExprValidatorCCC(const RecordType *RTy)
Kaelyn Takatae9e4ecf2014-11-11 23:00:40 +0000574 : Record(RTy->getDecl()) {
575 // Don't add bare keywords to the consumer since they will always fail
576 // validation by virtue of not being associated with any decls.
577 WantTypeSpecifiers = false;
578 WantExpressionKeywords = false;
579 WantCXXNamedCasts = false;
580 WantFunctionLikeCasts = false;
581 WantRemainingKeywords = false;
582 }
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000583
Craig Toppere14c0f82014-03-12 04:55:44 +0000584 bool ValidateCandidate(const TypoCorrection &candidate) override {
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000585 NamedDecl *ND = candidate.getCorrectionDecl();
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000586 // Don't accept candidates that cannot be member functions, constants,
587 // variables, or templates.
588 if (!ND || !(isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)))
589 return false;
590
591 // Accept candidates that occur in the current record.
592 if (Record->containsDecl(ND))
593 return true;
594
595 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) {
596 // Accept candidates that occur in any of the current class' base classes.
Aaron Ballman574705e2014-03-13 15:41:46 +0000597 for (const auto &BS : RD->bases()) {
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000598 if (const RecordType *BSTy =
599 dyn_cast_or_null<RecordType>(BS.getType().getTypePtrOrNull())) {
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000600 if (BSTy->getDecl()->containsDecl(ND))
601 return true;
602 }
603 }
604 }
605
606 return false;
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000607 }
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000608
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000609private:
Kaelyn Uhrain8aa8da82013-10-19 00:05:00 +0000610 const RecordDecl *const Record;
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000611};
612
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000613}
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +0000614
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000615static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000616 Expr *BaseExpr,
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000617 const RecordType *RTy,
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000618 SourceLocation OpLoc, bool IsArrow,
619 CXXScopeSpec &SS, bool HasTemplateArgs,
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000620 TypoExpr *&TE) {
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000621 SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000622 RecordDecl *RDecl = RTy->getDecl();
Douglas Gregor3024f072012-04-16 07:05:22 +0000623 if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&
624 SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
Douglas Gregor7bfb2d02012-05-04 16:32:21 +0000625 diag::err_typecheck_incomplete_tag,
626 BaseRange))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000627 return true;
628
629 if (HasTemplateArgs) {
630 // LookupTemplateName doesn't expect these both to exist simultaneously.
631 QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0);
632
633 bool MOUS;
Craig Topperc3ec1492014-05-26 06:22:03 +0000634 SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000635 return false;
636 }
637
638 DeclContext *DC = RDecl;
639 if (SS.isSet()) {
640 // If the member name was a qualified-id, look into the
641 // nested-name-specifier.
642 DC = SemaRef.computeDeclContext(SS, false);
643
644 if (SemaRef.RequireCompleteDeclContext(SS, DC)) {
645 SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag)
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000646 << SS.getRange() << DC;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000647 return true;
648 }
649
650 assert(DC && "Cannot handle non-computable dependent contexts in lookup");
651
652 if (!isa<TypeDecl>(DC)) {
653 SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_nonclass)
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000654 << DC << SS.getRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000655 return true;
656 }
657 }
658
659 // The record definition is complete, now look up the member.
Nikola Smiljanicfce370e2014-12-01 23:15:01 +0000660 SemaRef.LookupQualifiedName(R, DC, SS);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000661
662 if (!R.empty())
663 return false;
664
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000665 DeclarationName Typo = R.getLookupName();
666 SourceLocation TypoLoc = R.getNameLoc();
David Blaikiea8173ba2015-09-28 23:48:55 +0000667
668 struct QueryState {
669 Sema &SemaRef;
670 DeclarationNameInfo NameInfo;
671 Sema::LookupNameKind LookupKind;
672 Sema::RedeclarationKind Redecl;
673 };
674 QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
675 R.isForRedeclaration() ? Sema::ForRedeclaration
676 : Sema::NotForRedeclaration};
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000677 TE = SemaRef.CorrectTypoDelayed(
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000678 R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
679 llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000680 [=, &SemaRef](const TypoCorrection &TC) {
681 if (TC) {
682 assert(!TC.isKeyword() &&
683 "Got a keyword as a correction for a member!");
684 bool DroppedSpecifier =
685 TC.WillReplaceSpecifier() &&
686 Typo.getAsString() == TC.getAsString(SemaRef.getLangOpts());
687 SemaRef.diagnoseTypo(TC, SemaRef.PDiag(diag::err_no_member_suggest)
688 << Typo << DC << DroppedSpecifier
689 << SS.getRange());
690 } else {
691 SemaRef.Diag(TypoLoc, diag::err_no_member) << Typo << DC << BaseRange;
692 }
693 },
694 [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable {
David Blaikiea8173ba2015-09-28 23:48:55 +0000695 LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl);
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000696 R.clear(); // Ensure there's no decls lingering in the shared state.
697 R.suppressDiagnostics();
698 R.setLookupName(TC.getCorrection());
699 for (NamedDecl *ND : TC)
700 R.addDecl(ND);
701 R.resolveKind();
702 return SemaRef.BuildMemberReferenceExpr(
703 BaseExpr, BaseExpr->getType(), OpLoc, IsArrow, SS, SourceLocation(),
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000704 nullptr, R, nullptr, nullptr);
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000705 },
Kaelyn Takatadb99de22014-11-11 23:00:38 +0000706 Sema::CTK_ErrorRecovery, DC);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000707
708 return false;
709}
710
Richard Smitha0edd302014-05-31 00:18:32 +0000711static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
712 ExprResult &BaseExpr, bool &IsArrow,
713 SourceLocation OpLoc, CXXScopeSpec &SS,
714 Decl *ObjCImpDecl, bool HasTemplateArgs);
715
Douglas Gregor5476205b2011-06-23 00:49:38 +0000716ExprResult
717Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
718 SourceLocation OpLoc, bool IsArrow,
719 CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000720 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000721 NamedDecl *FirstQualifierInScope,
722 const DeclarationNameInfo &NameInfo,
Richard Smitha0edd302014-05-31 00:18:32 +0000723 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000724 const Scope *S,
Richard Smitha0edd302014-05-31 00:18:32 +0000725 ActOnMemberAccessExtraArgs *ExtraArgs) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000726 if (BaseType->isDependentType() ||
727 (SS.isSet() && isDependentScopeSpecifier(SS)))
728 return ActOnDependentMemberExpr(Base, BaseType,
729 IsArrow, OpLoc,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000730 SS, TemplateKWLoc, FirstQualifierInScope,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000731 NameInfo, TemplateArgs);
732
733 LookupResult R(*this, NameInfo, LookupMemberName);
734
735 // Implicit member accesses.
736 if (!Base) {
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000737 TypoExpr *TE = nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000738 QualType RecordTy = BaseType;
739 if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +0000740 if (LookupMemberExprInRecord(*this, R, nullptr,
741 RecordTy->getAs<RecordType>(), OpLoc, IsArrow,
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000742 SS, TemplateArgs != nullptr, TE))
Douglas Gregor5476205b2011-06-23 00:49:38 +0000743 return ExprError();
Kaelyn Takata2e764b82014-11-11 23:26:58 +0000744 if (TE)
745 return TE;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000746
747 // Explicit member accesses.
748 } else {
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000749 ExprResult BaseResult = Base;
Richard Smitha0edd302014-05-31 00:18:32 +0000750 ExprResult Result = LookupMemberExpr(
751 *this, R, BaseResult, IsArrow, OpLoc, SS,
752 ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
753 TemplateArgs != nullptr);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000754
755 if (BaseResult.isInvalid())
756 return ExprError();
Nikola Smiljanic01a75982014-05-29 10:55:11 +0000757 Base = BaseResult.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000758
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000759 if (Result.isInvalid())
Douglas Gregor5476205b2011-06-23 00:49:38 +0000760 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000761
762 if (Result.get())
Benjamin Kramer62b95d82012-08-23 21:35:17 +0000763 return Result;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000764
765 // LookupMemberExpr can modify Base, and thus change BaseType
766 BaseType = Base->getType();
767 }
768
769 return BuildMemberReferenceExpr(Base, BaseType,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000770 OpLoc, IsArrow, SS, TemplateKWLoc,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000771 FirstQualifierInScope, R, TemplateArgs, S,
Richard Smitha0edd302014-05-31 00:18:32 +0000772 false, ExtraArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000773}
774
Douglas Gregor5476205b2011-06-23 00:49:38 +0000775ExprResult
776Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
777 SourceLocation loc,
778 IndirectFieldDecl *indirectField,
Eli Friedmancccd0642013-07-16 00:01:31 +0000779 DeclAccessPair foundDecl,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000780 Expr *baseObjectExpr,
781 SourceLocation opLoc) {
782 // First, build the expression that refers to the base object.
783
784 bool baseObjectIsPointer = false;
785 Qualifiers baseQuals;
786
787 // Case 1: the base of the indirect field is not a field.
788 VarDecl *baseVariable = indirectField->getVarDecl();
789 CXXScopeSpec EmptySS;
790 if (baseVariable) {
791 assert(baseVariable->getType()->isRecordType());
792
793 // In principle we could have a member access expression that
794 // accesses an anonymous struct/union that's a static member of
795 // the base object's class. However, under the current standard,
796 // static data members cannot be anonymous structs or unions.
797 // Supporting this is as easy as building a MemberExpr here.
798 assert(!baseObjectExpr && "anonymous struct/union is static data member?");
799
800 DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
801
802 ExprResult result
803 = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
804 if (result.isInvalid()) return ExprError();
805
Nikola Smiljanic01a75982014-05-29 10:55:11 +0000806 baseObjectExpr = result.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000807 baseObjectIsPointer = false;
808 baseQuals = baseObjectExpr->getType().getQualifiers();
809
810 // Case 2: the base of the indirect field is a field and the user
811 // wrote a member expression.
812 } else if (baseObjectExpr) {
813 // The caller provided the base object expression. Determine
814 // whether its a pointer and whether it adds any qualifiers to the
815 // anonymous struct/union fields we're looking into.
816 QualType objectType = baseObjectExpr->getType();
817
818 if (const PointerType *ptr = objectType->getAs<PointerType>()) {
819 baseObjectIsPointer = true;
820 objectType = ptr->getPointeeType();
821 } else {
822 baseObjectIsPointer = false;
823 }
824 baseQuals = objectType.getQualifiers();
825
826 // Case 3: the base of the indirect field is a field and we should
827 // build an implicit member access.
828 } else {
829 // We've found a member of an anonymous struct/union that is
830 // inside a non-anonymous struct/union, so in a well-formed
831 // program our base object expression is "this".
Douglas Gregor09deffa2011-10-18 16:47:30 +0000832 QualType ThisTy = getCurrentThisType();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000833 if (ThisTy.isNull()) {
834 Diag(loc, diag::err_invalid_member_use_in_static_method)
835 << indirectField->getDeclName();
836 return ExprError();
837 }
838
839 // Our base object expression is "this".
Eli Friedman73a04092012-01-07 04:59:52 +0000840 CheckCXXThisCapture(loc);
Douglas Gregor5476205b2011-06-23 00:49:38 +0000841 baseObjectExpr
842 = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true);
843 baseObjectIsPointer = true;
844 baseQuals = ThisTy->castAs<PointerType>()->getPointeeType().getQualifiers();
845 }
846
847 // Build the implicit member references to the field of the
848 // anonymous struct/union.
849 Expr *result = baseObjectExpr;
850 IndirectFieldDecl::chain_iterator
851 FI = indirectField->chain_begin(), FEnd = indirectField->chain_end();
852
853 // Build the first member access in the chain with full information.
854 if (!baseVariable) {
855 FieldDecl *field = cast<FieldDecl>(*FI);
856
Douglas Gregor5476205b2011-06-23 00:49:38 +0000857 // Make a nameInfo that properly uses the anonymous name.
858 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000859
Richard Smith7873de02016-08-11 22:25:46 +0000860 result = BuildFieldReferenceExpr(result, baseObjectIsPointer,
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000861 SourceLocation(), EmptySS, field,
862 foundDecl, memberNameInfo).get();
Eli Friedmancccd0642013-07-16 00:01:31 +0000863 if (!result)
864 return ExprError();
865
Douglas Gregor5476205b2011-06-23 00:49:38 +0000866 // FIXME: check qualified member access
867 }
868
869 // In all cases, we should now skip the first declaration in the chain.
870 ++FI;
871
872 while (FI != FEnd) {
873 FieldDecl *field = cast<FieldDecl>(*FI++);
Eli Friedmancccd0642013-07-16 00:01:31 +0000874
Douglas Gregor5476205b2011-06-23 00:49:38 +0000875 // FIXME: these are somewhat meaningless
876 DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
Eli Friedmancccd0642013-07-16 00:01:31 +0000877 DeclAccessPair fakeFoundDecl =
878 DeclAccessPair::make(field, field->getAccess());
879
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000880 result =
Richard Smith7873de02016-08-11 22:25:46 +0000881 BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(),
882 (FI == FEnd ? SS : EmptySS), field,
883 fakeFoundDecl, memberNameInfo)
884 .get();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000885 }
886
Nikola Smiljanic03ff2592014-05-29 14:05:12 +0000887 return result;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000888}
889
John McCall5e77d762013-04-16 07:28:30 +0000890static ExprResult
891BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
892 const CXXScopeSpec &SS,
893 MSPropertyDecl *PD,
894 const DeclarationNameInfo &NameInfo) {
895 // Property names are always simple identifiers and therefore never
896 // require any interesting additional storage.
897 return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
898 S.Context.PseudoObjectTy, VK_LValue,
899 SS.getWithLocInContext(S.Context),
900 NameInfo.getLoc());
901}
902
Douglas Gregor5476205b2011-06-23 00:49:38 +0000903/// \brief Build a MemberExpr AST node.
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000904static MemberExpr *BuildMemberExpr(
905 Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow,
906 SourceLocation OpLoc, const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
907 ValueDecl *Member, DeclAccessPair FoundDecl,
908 const DeclarationNameInfo &MemberNameInfo, QualType Ty, ExprValueKind VK,
909 ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = nullptr) {
Richard Smith08b12f12011-10-27 22:11:44 +0000910 assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +0000911 MemberExpr *E = MemberExpr::Create(
912 C, Base, isArrow, OpLoc, SS.getWithLocInContext(C), TemplateKWLoc, Member,
913 FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK);
Eli Friedmanfa0df832012-02-02 03:46:19 +0000914 SemaRef.MarkMemberReferenced(E);
915 return E;
Douglas Gregor5476205b2011-06-23 00:49:38 +0000916}
917
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000918/// \brief Determine if the given scope is within a function-try-block handler.
919static bool IsInFnTryBlockHandler(const Scope *S) {
920 // Walk the scope stack until finding a FnTryCatchScope, or leave the
921 // function scope. If a FnTryCatchScope is found, check whether the TryScope
922 // flag is set. If it is not, it's a function-try-block handler.
923 for (; S != S->getFnParent(); S = S->getParent()) {
924 if (S->getFlags() & Scope::FnTryCatchScope)
925 return (S->getFlags() & Scope::TryScope) != Scope::TryScope;
926 }
927 return false;
928}
929
Faisal Valie7f8fb92016-02-22 02:24:29 +0000930static VarDecl *
931getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl,
932 const TemplateArgumentListInfo *TemplateArgs,
933 const DeclarationNameInfo &MemberNameInfo,
934 SourceLocation TemplateKWLoc) {
935
936 if (!TemplateArgs) {
937 S.Diag(MemberNameInfo.getBeginLoc(), diag::err_template_decl_ref)
938 << /*Variable template*/ 1 << MemberNameInfo.getName()
939 << MemberNameInfo.getSourceRange();
940
941 S.Diag(VarTempl->getLocation(), diag::note_template_decl_here);
942
943 return nullptr;
944 }
945 DeclResult VDecl = S.CheckVarTemplateId(
946 VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs);
947 if (VDecl.isInvalid())
948 return nullptr;
949 VarDecl *Var = cast<VarDecl>(VDecl.get());
950 if (!Var->getTemplateSpecializationKind())
951 Var->setTemplateSpecializationKind(TSK_ImplicitInstantiation,
952 MemberNameInfo.getLoc());
953 return Var;
954}
955
Douglas Gregor5476205b2011-06-23 00:49:38 +0000956ExprResult
957Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
958 SourceLocation OpLoc, bool IsArrow,
959 const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +0000960 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +0000961 NamedDecl *FirstQualifierInScope,
962 LookupResult &R,
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000963 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +0000964 const Scope *S,
Kaelyn Uhrain76e07342012-04-25 19:49:54 +0000965 bool SuppressQualifierCheck,
966 ActOnMemberAccessExtraArgs *ExtraArgs) {
Douglas Gregor5476205b2011-06-23 00:49:38 +0000967 QualType BaseType = BaseExprType;
968 if (IsArrow) {
969 assert(BaseType->isPointerType());
John McCall526ab472011-10-25 17:37:35 +0000970 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
Douglas Gregor5476205b2011-06-23 00:49:38 +0000971 }
972 R.setBaseObjectType(BaseType);
Richard Smith4baaa5a2016-12-03 01:14:32 +0000973
974 // C++1z [expr.ref]p2:
975 // For the first option (dot) the first expression shall be a glvalue [...]
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000976 if (!IsArrow && BaseExpr && BaseExpr->isRValue()) {
Richard Smith4baaa5a2016-12-03 01:14:32 +0000977 ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
978 if (Converted.isInvalid())
979 return ExprError();
980 BaseExpr = Converted.get();
981 }
Faisal Valia17d19f2013-11-07 05:17:06 +0000982
983 LambdaScopeInfo *const CurLSI = getCurLambda();
984 // If this is an implicit member reference and the overloaded
985 // name refers to both static and non-static member functions
986 // (i.e. BaseExpr is null) and if we are currently processing a lambda,
987 // check if we should/can capture 'this'...
988 // Keep this example in mind:
989 // struct X {
990 // void f(int) { }
991 // static void f(double) { }
992 //
993 // int g() {
994 // auto L = [=](auto a) {
995 // return [](int i) {
996 // return [=](auto b) {
997 // f(b);
998 // //f(decltype(a){});
999 // };
1000 // };
1001 // };
1002 // auto M = L(0.0);
1003 // auto N = M(3);
1004 // N(5.32); // OK, must not error.
1005 // return 0;
1006 // }
1007 // };
1008 //
1009 if (!BaseExpr && CurLSI) {
1010 SourceLocation Loc = R.getNameLoc();
1011 if (SS.getRange().isValid())
1012 Loc = SS.getRange().getBegin();
1013 DeclContext *EnclosingFunctionCtx = CurContext->getParent()->getParent();
1014 // If the enclosing function is not dependent, then this lambda is
1015 // capture ready, so if we can capture this, do so.
1016 if (!EnclosingFunctionCtx->isDependentContext()) {
1017 // If the current lambda and all enclosing lambdas can capture 'this' -
1018 // then go ahead and capture 'this' (since our unresolved overload set
1019 // contains both static and non-static member functions).
1020 if (!CheckCXXThisCapture(Loc, /*Explcit*/false, /*Diagnose*/false))
1021 CheckCXXThisCapture(Loc);
1022 } else if (CurContext->isDependentContext()) {
1023 // ... since this is an implicit member reference, that might potentially
1024 // involve a 'this' capture, mark 'this' for potential capture in
1025 // enclosing lambdas.
1026 if (CurLSI->ImpCaptureStyle != CurLSI->ImpCap_None)
1027 CurLSI->addPotentialThisCapture(Loc);
1028 }
1029 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001030 const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
1031 DeclarationName MemberName = MemberNameInfo.getName();
1032 SourceLocation MemberLoc = MemberNameInfo.getLoc();
1033
1034 if (R.isAmbiguous())
1035 return ExprError();
1036
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001037 // [except.handle]p10: Referring to any non-static member or base class of an
1038 // object in the handler for a function-try-block of a constructor or
1039 // destructor for that object results in undefined behavior.
1040 const auto *FD = getCurFunctionDecl();
1041 if (S && BaseExpr && FD &&
1042 (isa<CXXDestructorDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
1043 isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts()) &&
1044 IsInFnTryBlockHandler(S))
1045 Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr)
1046 << isa<CXXDestructorDecl>(FD);
1047
Douglas Gregor5476205b2011-06-23 00:49:38 +00001048 if (R.empty()) {
1049 // Rederive where we looked up.
1050 DeclContext *DC = (SS.isSet()
1051 ? computeDeclContext(SS, false)
1052 : BaseType->getAs<RecordType>()->getDecl());
1053
Kaelyn Uhrain76e07342012-04-25 19:49:54 +00001054 if (ExtraArgs) {
1055 ExprResult RetryExpr;
1056 if (!IsArrow && BaseExpr) {
Kaelyn Uhraind4ea98a2012-05-01 01:17:53 +00001057 SFINAETrap Trap(*this, true);
Kaelyn Uhrain76e07342012-04-25 19:49:54 +00001058 ParsedType ObjectType;
1059 bool MayBePseudoDestructor = false;
1060 RetryExpr = ActOnStartCXXMemberReference(getCurScope(), BaseExpr,
1061 OpLoc, tok::arrow, ObjectType,
1062 MayBePseudoDestructor);
1063 if (RetryExpr.isUsable() && !Trap.hasErrorOccurred()) {
1064 CXXScopeSpec TempSS(SS);
1065 RetryExpr = ActOnMemberAccessExpr(
1066 ExtraArgs->S, RetryExpr.get(), OpLoc, tok::arrow, TempSS,
David Majnemerced8bdf2015-02-25 17:36:15 +00001067 TemplateKWLoc, ExtraArgs->Id, ExtraArgs->ObjCImpDecl);
Kaelyn Uhrain76e07342012-04-25 19:49:54 +00001068 }
1069 if (Trap.hasErrorOccurred())
1070 RetryExpr = ExprError();
1071 }
1072 if (RetryExpr.isUsable()) {
1073 Diag(OpLoc, diag::err_no_member_overloaded_arrow)
1074 << MemberName << DC << FixItHint::CreateReplacement(OpLoc, "->");
1075 return RetryExpr;
1076 }
1077 }
1078
Douglas Gregor5476205b2011-06-23 00:49:38 +00001079 Diag(R.getNameLoc(), diag::err_no_member)
1080 << MemberName << DC
1081 << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
1082 return ExprError();
1083 }
1084
1085 // Diagnose lookups that find only declarations from a non-base
1086 // type. This is possible for either qualified lookups (which may
1087 // have been qualified with an unrelated type) or implicit member
1088 // expressions (which were found with unqualified lookup and thus
1089 // may have come from an enclosing scope). Note that it's okay for
1090 // lookup to find declarations from a non-base type as long as those
1091 // aren't the ones picked by overload resolution.
1092 if ((SS.isSet() || !BaseExpr ||
1093 (isa<CXXThisExpr>(BaseExpr) &&
1094 cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
1095 !SuppressQualifierCheck &&
1096 CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
1097 return ExprError();
Fariborz Jahanian502d2ee2011-10-17 21:00:22 +00001098
Douglas Gregor5476205b2011-06-23 00:49:38 +00001099 // Construct an unresolved result if we in fact got an unresolved
1100 // result.
1101 if (R.isOverloadedResult() || R.isUnresolvableResult()) {
1102 // Suppress any lookup-related diagnostics; we'll do these when we
1103 // pick a member.
1104 R.suppressDiagnostics();
1105
1106 UnresolvedMemberExpr *MemExpr
1107 = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(),
1108 BaseExpr, BaseExprType,
1109 IsArrow, OpLoc,
1110 SS.getWithLocInContext(Context),
Abramo Bagnara7945c982012-01-27 09:46:47 +00001111 TemplateKWLoc, MemberNameInfo,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001112 TemplateArgs, R.begin(), R.end());
1113
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001114 return MemExpr;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001115 }
1116
1117 assert(R.isSingleResult());
1118 DeclAccessPair FoundDecl = R.begin().getPair();
1119 NamedDecl *MemberDecl = R.getFoundDecl();
1120
1121 // FIXME: diagnose the presence of template arguments now.
1122
1123 // If the decl being referenced had an error, return an error for this
1124 // sub-expr without emitting another error, in order to avoid cascading
1125 // error cases.
1126 if (MemberDecl->isInvalidDecl())
1127 return ExprError();
1128
1129 // Handle the implicit-member-access case.
1130 if (!BaseExpr) {
1131 // If this is not an instance member, convert to a non-member access.
Faisal Valie7f8fb92016-02-22 02:24:29 +00001132 if (!MemberDecl->isCXXInstanceMember()) {
1133 // If this is a variable template, get the instantiated variable
1134 // declaration corresponding to the supplied template arguments
1135 // (while emitting diagnostics as necessary) that will be referenced
1136 // by this expression.
Faisal Vali640dc752016-02-25 05:09:30 +00001137 assert((!TemplateArgs || isa<VarTemplateDecl>(MemberDecl)) &&
1138 "How did we get template arguments here sans a variable template");
Faisal Valie7f8fb92016-02-22 02:24:29 +00001139 if (isa<VarTemplateDecl>(MemberDecl)) {
1140 MemberDecl = getVarTemplateSpecialization(
1141 *this, cast<VarTemplateDecl>(MemberDecl), TemplateArgs,
1142 R.getLookupNameInfo(), TemplateKWLoc);
1143 if (!MemberDecl)
1144 return ExprError();
1145 }
Faisal Vali640dc752016-02-25 05:09:30 +00001146 return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl,
1147 FoundDecl, TemplateArgs);
Faisal Valie7f8fb92016-02-22 02:24:29 +00001148 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001149 SourceLocation Loc = R.getNameLoc();
1150 if (SS.getRange().isValid())
1151 Loc = SS.getRange().getBegin();
Eli Friedman73a04092012-01-07 04:59:52 +00001152 CheckCXXThisCapture(Loc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001153 BaseExpr = new (Context) CXXThisExpr(Loc, BaseExprType,/*isImplicit=*/true);
1154 }
1155
Douglas Gregor5476205b2011-06-23 00:49:38 +00001156 // Check the use of this member.
Davide Italianof179e362015-07-22 00:30:58 +00001157 if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001158 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001159
Douglas Gregor5476205b2011-06-23 00:49:38 +00001160 if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
Richard Smith7873de02016-08-11 22:25:46 +00001161 return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
1162 MemberNameInfo);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001163
John McCall5e77d762013-04-16 07:28:30 +00001164 if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
1165 return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
1166 MemberNameInfo);
1167
Douglas Gregor5476205b2011-06-23 00:49:38 +00001168 if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
1169 // We may have found a field within an anonymous union or struct
1170 // (C++ [class.union]).
1171 return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
Eli Friedmancccd0642013-07-16 00:01:31 +00001172 FoundDecl, BaseExpr,
1173 OpLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001174
1175 if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001176 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1177 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001178 Var->getType().getNonReferenceType(), VK_LValue,
1179 OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001180 }
1181
1182 if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
1183 ExprValueKind valueKind;
1184 QualType type;
1185 if (MemberFn->isInstance()) {
1186 valueKind = VK_RValue;
1187 type = Context.BoundMemberTy;
1188 } else {
1189 valueKind = VK_LValue;
1190 type = MemberFn->getType();
1191 }
1192
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001193 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1194 TemplateKWLoc, MemberFn, FoundDecl, MemberNameInfo,
1195 type, valueKind, OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001196 }
1197 assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
1198
1199 if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
Aaron Ballmanf4cb2be2015-03-24 15:07:53 +00001200 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1201 TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
1202 Enum->getType(), VK_RValue, OK_Ordinary);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001203 }
Faisal Valie7f8fb92016-02-22 02:24:29 +00001204 if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
1205 if (VarDecl *Var = getVarTemplateSpecialization(
1206 *this, VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc))
1207 return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS,
1208 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
1209 Var->getType().getNonReferenceType(), VK_LValue,
1210 OK_Ordinary);
1211 return ExprError();
1212 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001213
Douglas Gregor5476205b2011-06-23 00:49:38 +00001214 // We found something that we didn't expect. Complain.
1215 if (isa<TypeDecl>(MemberDecl))
1216 Diag(MemberLoc, diag::err_typecheck_member_reference_type)
1217 << MemberName << BaseType << int(IsArrow);
1218 else
1219 Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
1220 << MemberName << BaseType << int(IsArrow);
1221
1222 Diag(MemberDecl->getLocation(), diag::note_member_declared_here)
1223 << MemberName;
1224 R.suppressDiagnostics();
1225 return ExprError();
1226}
1227
1228/// Given that normal member access failed on the given expression,
1229/// and given that the expression's type involves builtin-id or
1230/// builtin-Class, decide whether substituting in the redefinition
1231/// types would be profitable. The redefinition type is whatever
1232/// this translation unit tried to typedef to id/Class; we store
1233/// it to the side and then re-use it in places like this.
1234static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base) {
1235 const ObjCObjectPointerType *opty
1236 = base.get()->getType()->getAs<ObjCObjectPointerType>();
1237 if (!opty) return false;
1238
1239 const ObjCObjectType *ty = opty->getObjectType();
1240
1241 QualType redef;
1242 if (ty->isObjCId()) {
Douglas Gregor97673472011-08-11 20:58:55 +00001243 redef = S.Context.getObjCIdRedefinitionType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001244 } else if (ty->isObjCClass()) {
Douglas Gregor97673472011-08-11 20:58:55 +00001245 redef = S.Context.getObjCClassRedefinitionType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001246 } else {
1247 return false;
1248 }
1249
1250 // Do the substitution as long as the redefinition type isn't just a
1251 // possibly-qualified pointer to builtin-id or builtin-Class again.
1252 opty = redef->getAs<ObjCObjectPointerType>();
Richard Trieuf20d9052012-10-12 17:48:40 +00001253 if (opty && !opty->getObjectType()->getInterface())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001254 return false;
1255
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001256 base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001257 return true;
1258}
1259
John McCall50a2c2c2011-10-11 23:14:30 +00001260static bool isRecordType(QualType T) {
1261 return T->isRecordType();
1262}
1263static bool isPointerToRecordType(QualType T) {
1264 if (const PointerType *PT = T->getAs<PointerType>())
1265 return PT->getPointeeType()->isRecordType();
1266 return false;
1267}
1268
Richard Smithcab9a7d2011-10-26 19:06:56 +00001269/// Perform conversions on the LHS of a member access expression.
1270ExprResult
1271Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
Eli Friedman9a766c42012-01-13 02:20:01 +00001272 if (IsArrow && !Base->getType()->isFunctionType())
1273 return DefaultFunctionArrayLvalueConversion(Base);
Richard Smithcab9a7d2011-10-26 19:06:56 +00001274
Eli Friedman9a766c42012-01-13 02:20:01 +00001275 return CheckPlaceholderExpr(Base);
Richard Smithcab9a7d2011-10-26 19:06:56 +00001276}
1277
Douglas Gregor5476205b2011-06-23 00:49:38 +00001278/// Look up the given member of the given non-type-dependent
1279/// expression. This can return in one of two ways:
1280/// * If it returns a sentinel null-but-valid result, the caller will
1281/// assume that lookup was performed and the results written into
1282/// the provided structure. It will take over from there.
1283/// * Otherwise, the returned expression will be produced in place of
1284/// an ordinary member expression.
1285///
1286/// The ObjCImpDecl bit is a gross hack that will need to be properly
1287/// fixed for ObjC++.
Richard Smitha0edd302014-05-31 00:18:32 +00001288static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
1289 ExprResult &BaseExpr, bool &IsArrow,
1290 SourceLocation OpLoc, CXXScopeSpec &SS,
1291 Decl *ObjCImpDecl, bool HasTemplateArgs) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001292 assert(BaseExpr.get() && "no base expression");
1293
1294 // Perform default conversions.
Richard Smitha0edd302014-05-31 00:18:32 +00001295 BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
John McCall50a2c2c2011-10-11 23:14:30 +00001296 if (BaseExpr.isInvalid())
1297 return ExprError();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001298
Douglas Gregor5476205b2011-06-23 00:49:38 +00001299 QualType BaseType = BaseExpr.get()->getType();
1300 assert(!BaseType->isDependentType());
1301
1302 DeclarationName MemberName = R.getLookupName();
1303 SourceLocation MemberLoc = R.getNameLoc();
1304
1305 // For later type-checking purposes, turn arrow accesses into dot
1306 // accesses. The only access type we support that doesn't follow
1307 // the C equivalence "a->b === (*a).b" is ObjC property accesses,
1308 // and those never use arrows, so this is unaffected.
1309 if (IsArrow) {
1310 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1311 BaseType = Ptr->getPointeeType();
1312 else if (const ObjCObjectPointerType *Ptr
1313 = BaseType->getAs<ObjCObjectPointerType>())
1314 BaseType = Ptr->getPointeeType();
1315 else if (BaseType->isRecordType()) {
1316 // Recover from arrow accesses to records, e.g.:
1317 // struct MyRecord foo;
1318 // foo->bar
1319 // This is actually well-formed in C++ if MyRecord has an
1320 // overloaded operator->, but that should have been dealt with
Kaelyn Uhrain0c51de42013-07-31 17:38:24 +00001321 // by now--or a diagnostic message already issued if a problem
1322 // was encountered while looking for the overloaded operator->.
Richard Smitha0edd302014-05-31 00:18:32 +00001323 if (!S.getLangOpts().CPlusPlus) {
1324 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
Kaelyn Uhrainbd6ddaa2013-10-31 20:32:56 +00001325 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1326 << FixItHint::CreateReplacement(OpLoc, ".");
1327 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001328 IsArrow = false;
Eli Friedman9a766c42012-01-13 02:20:01 +00001329 } else if (BaseType->isFunctionType()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001330 goto fail;
1331 } else {
Richard Smitha0edd302014-05-31 00:18:32 +00001332 S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001333 << BaseType << BaseExpr.get()->getSourceRange();
1334 return ExprError();
1335 }
1336 }
1337
1338 // Handle field access to simple records.
1339 if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
Kaelyn Takatafe408a72014-10-27 18:07:46 +00001340 TypoExpr *TE = nullptr;
Kaelyn Takata5c3dc4b2014-11-11 23:26:54 +00001341 if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy,
Kaelyn Takata2e764b82014-11-11 23:26:58 +00001342 OpLoc, IsArrow, SS, HasTemplateArgs, TE))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001343 return ExprError();
1344
1345 // Returning valid-but-null is how we indicate to the caller that
Kaelyn Takatafe408a72014-10-27 18:07:46 +00001346 // the lookup result was filled in. If typo correction was attempted and
1347 // failed, the lookup result will have been cleared--that combined with the
1348 // valid-but-null ExprResult will trigger the appropriate diagnostics.
1349 return ExprResult(TE);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001350 }
1351
1352 // Handle ivar access to Objective-C objects.
1353 if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
Douglas Gregorbcc95392011-10-10 16:09:49 +00001354 if (!SS.isEmpty() && !SS.isInvalid()) {
Richard Smitha0edd302014-05-31 00:18:32 +00001355 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
Douglas Gregor12340e52011-10-09 23:22:49 +00001356 << 1 << SS.getScopeRep()
1357 << FixItHint::CreateRemoval(SS.getRange());
1358 SS.clear();
1359 }
Richard Smitha0edd302014-05-31 00:18:32 +00001360
Douglas Gregor5476205b2011-06-23 00:49:38 +00001361 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1362
1363 // There are three cases for the base type:
1364 // - builtin id (qualified or unqualified)
1365 // - builtin Class (qualified or unqualified)
1366 // - an interface
1367 ObjCInterfaceDecl *IDecl = OTy->getInterface();
1368 if (!IDecl) {
Richard Smitha0edd302014-05-31 00:18:32 +00001369 if (S.getLangOpts().ObjCAutoRefCount &&
Douglas Gregor5476205b2011-06-23 00:49:38 +00001370 (OTy->isObjCId() || OTy->isObjCClass()))
1371 goto fail;
1372 // There's an implicit 'isa' ivar on all objects.
1373 // But we only actually find it this way on objects of type 'id',
Eric Christopherae6b9d22012-08-16 23:50:37 +00001374 // apparently.
Fariborz Jahanian84510742013-03-27 21:19:25 +00001375 if (OTy->isObjCId() && Member->isStr("isa"))
Richard Smitha0edd302014-05-31 00:18:32 +00001376 return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1377 OpLoc, S.Context.getObjCClassType());
1378 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1379 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001380 ObjCImpDecl, HasTemplateArgs);
1381 goto fail;
1382 }
Richard Smitha0edd302014-05-31 00:18:32 +00001383
1384 if (S.RequireCompleteType(OpLoc, BaseType,
1385 diag::err_typecheck_incomplete_tag,
1386 BaseExpr.get()))
Douglas Gregor5dbf4eb2012-01-02 17:18:37 +00001387 return ExprError();
Craig Topperc3ec1492014-05-26 06:22:03 +00001388
1389 ObjCInterfaceDecl *ClassDeclared = nullptr;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001390 ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1391
1392 if (!IV) {
1393 // Attempt to correct for typos in ivar names.
Kaelyn Takata89c881b2014-10-27 18:07:29 +00001394 auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>();
1395 Validator->IsObjCIvarLookup = IsArrow;
Richard Smitha0edd302014-05-31 00:18:32 +00001396 if (TypoCorrection Corrected = S.CorrectTypo(
1397 R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
Kaelyn Takata89c881b2014-10-27 18:07:29 +00001398 std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) {
Kaelyn Uhrain3658e6a2012-01-13 21:28:55 +00001399 IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
Richard Smitha0edd302014-05-31 00:18:32 +00001400 S.diagnoseTypo(
1401 Corrected,
1402 S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1403 << IDecl->getDeclName() << MemberName);
Richard Smithf9b15102013-08-17 00:46:16 +00001404
Ted Kremenek679b4782012-03-17 00:53:39 +00001405 // Figure out the class that declares the ivar.
1406 assert(!ClassDeclared);
Saleem Abdulrasool765a2192016-11-17 17:10:54 +00001407
Ted Kremenek679b4782012-03-17 00:53:39 +00001408 Decl *D = cast<Decl>(IV->getDeclContext());
Saleem Abdulrasool765a2192016-11-17 17:10:54 +00001409 if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1410 D = Category->getClassInterface();
1411
1412 if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1413 ClassDeclared = Implementation->getClassInterface();
1414 else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1415 ClassDeclared = Interface;
1416
1417 assert(ClassDeclared && "cannot query interface");
Douglas Gregor5476205b2011-06-23 00:49:38 +00001418 } else {
Manman Ren5b786402016-01-28 18:49:28 +00001419 if (IsArrow &&
1420 IDecl->FindPropertyDeclaration(
1421 Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
Richard Smitha0edd302014-05-31 00:18:32 +00001422 S.Diag(MemberLoc, diag::err_property_found_suggest)
1423 << Member << BaseExpr.get()->getType()
1424 << FixItHint::CreateReplacement(OpLoc, ".");
Fariborz Jahanianc297cd82011-06-28 00:00:52 +00001425 return ExprError();
1426 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001427
Richard Smitha0edd302014-05-31 00:18:32 +00001428 S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1429 << IDecl->getDeclName() << MemberName
1430 << BaseExpr.get()->getSourceRange();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001431 return ExprError();
1432 }
1433 }
Richard Smitha0edd302014-05-31 00:18:32 +00001434
Ted Kremenek679b4782012-03-17 00:53:39 +00001435 assert(ClassDeclared);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001436
1437 // If the decl being referenced had an error, return an error for this
1438 // sub-expr without emitting another error, in order to avoid cascading
1439 // error cases.
1440 if (IV->isInvalidDecl())
1441 return ExprError();
1442
1443 // Check whether we can reference this field.
Richard Smitha0edd302014-05-31 00:18:32 +00001444 if (S.DiagnoseUseOfDecl(IV, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001445 return ExprError();
1446 if (IV->getAccessControl() != ObjCIvarDecl::Public &&
1447 IV->getAccessControl() != ObjCIvarDecl::Package) {
Craig Topperc3ec1492014-05-26 06:22:03 +00001448 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
Richard Smitha0edd302014-05-31 00:18:32 +00001449 if (ObjCMethodDecl *MD = S.getCurMethodDecl())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001450 ClassOfMethodDecl = MD->getClassInterface();
Richard Smitha0edd302014-05-31 00:18:32 +00001451 else if (ObjCImpDecl && S.getCurFunctionDecl()) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001452 // Case of a c-function declared inside an objc implementation.
1453 // FIXME: For a c-style function nested inside an objc implementation
1454 // class, there is no implementation context available, so we pass
1455 // down the context as argument to this routine. Ideally, this context
1456 // need be passed down in the AST node and somehow calculated from the
1457 // AST for a function decl.
1458 if (ObjCImplementationDecl *IMPD =
1459 dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1460 ClassOfMethodDecl = IMPD->getClassInterface();
1461 else if (ObjCCategoryImplDecl* CatImplClass =
1462 dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1463 ClassOfMethodDecl = CatImplClass->getClassInterface();
1464 }
Richard Smitha0edd302014-05-31 00:18:32 +00001465 if (!S.getLangOpts().DebuggerSupport) {
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001466 if (IV->getAccessControl() == ObjCIvarDecl::Private) {
1467 if (!declaresSameEntity(ClassDeclared, IDecl) ||
1468 !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
Richard Smithf8812672016-12-02 22:38:31 +00001469 S.Diag(MemberLoc, diag::err_private_ivar_access)
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001470 << IV->getDeclName();
1471 } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1472 // @protected
Richard Smithf8812672016-12-02 22:38:31 +00001473 S.Diag(MemberLoc, diag::err_protected_ivar_access)
Richard Smitha0edd302014-05-31 00:18:32 +00001474 << IV->getDeclName();
Fariborz Jahaniand6cb4a82012-03-07 00:58:41 +00001475 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001476 }
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001477 bool warn = true;
Richard Smitha0edd302014-05-31 00:18:32 +00001478 if (S.getLangOpts().ObjCAutoRefCount) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001479 Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1480 if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1481 if (UO->getOpcode() == UO_Deref)
1482 BaseExp = UO->getSubExpr()->IgnoreParenCasts();
1483
1484 if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001485 if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
Richard Smithf8812672016-12-02 22:38:31 +00001486 S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
Fariborz Jahanian285a7cc2012-08-07 23:48:10 +00001487 warn = false;
1488 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001489 }
Fariborz Jahaniana5063a62012-08-08 16:41:04 +00001490 if (warn) {
Richard Smitha0edd302014-05-31 00:18:32 +00001491 if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001492 ObjCMethodFamily MF = MD->getMethodFamily();
1493 warn = (MF != OMF_init && MF != OMF_dealloc &&
Fariborz Jahaniana934a022013-02-14 19:07:19 +00001494 MF != OMF_finalize &&
Richard Smitha0edd302014-05-31 00:18:32 +00001495 !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001496 }
1497 if (warn)
Richard Smitha0edd302014-05-31 00:18:32 +00001498 S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
Fariborz Jahaniana7c9f882012-08-07 16:38:44 +00001499 }
Jordan Rose657b5f42012-09-28 22:21:35 +00001500
Richard Smitha0edd302014-05-31 00:18:32 +00001501 ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
Douglas Gregore83b9562015-07-07 03:57:53 +00001502 IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1503 IsArrow);
Jordan Rose657b5f42012-09-28 22:21:35 +00001504
Richard Smitha0edd302014-05-31 00:18:32 +00001505 if (S.getLangOpts().ObjCAutoRefCount) {
Jordan Rose657b5f42012-09-28 22:21:35 +00001506 if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
Alp Tokerd4a3f0e2014-06-15 23:30:39 +00001507 if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
Richard Smitha0edd302014-05-31 00:18:32 +00001508 S.recordUseOfEvaluatedWeak(Result);
Jordan Rose657b5f42012-09-28 22:21:35 +00001509 }
1510 }
1511
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001512 return Result;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001513 }
1514
1515 // Objective-C property access.
1516 const ObjCObjectPointerType *OPT;
1517 if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
Douglas Gregorbcc95392011-10-10 16:09:49 +00001518 if (!SS.isEmpty() && !SS.isInvalid()) {
Richard Smitha0edd302014-05-31 00:18:32 +00001519 S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1520 << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
Douglas Gregor12340e52011-10-09 23:22:49 +00001521 SS.clear();
1522 }
1523
Douglas Gregor5476205b2011-06-23 00:49:38 +00001524 // This actually uses the base as an r-value.
Richard Smitha0edd302014-05-31 00:18:32 +00001525 BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001526 if (BaseExpr.isInvalid())
1527 return ExprError();
1528
Richard Smitha0edd302014-05-31 00:18:32 +00001529 assert(S.Context.hasSameUnqualifiedType(BaseType,
1530 BaseExpr.get()->getType()));
Douglas Gregor5476205b2011-06-23 00:49:38 +00001531
1532 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1533
1534 const ObjCObjectType *OT = OPT->getObjectType();
1535
1536 // id, with and without qualifiers.
1537 if (OT->isObjCId()) {
1538 // Check protocols on qualified interfaces.
Richard Smitha0edd302014-05-31 00:18:32 +00001539 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
1540 if (Decl *PMDecl =
1541 FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001542 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1543 // Check the use of this declaration
Richard Smitha0edd302014-05-31 00:18:32 +00001544 if (S.DiagnoseUseOfDecl(PD, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001545 return ExprError();
1546
Richard Smitha0edd302014-05-31 00:18:32 +00001547 return new (S.Context)
1548 ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001549 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001550 }
1551
1552 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
1553 // Check the use of this method.
Richard Smitha0edd302014-05-31 00:18:32 +00001554 if (S.DiagnoseUseOfDecl(OMD, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001555 return ExprError();
1556 Selector SetterSel =
Richard Smitha0edd302014-05-31 00:18:32 +00001557 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1558 S.PP.getSelectorTable(),
Adrian Prantla4ce9062013-06-07 22:29:12 +00001559 Member);
Craig Topperc3ec1492014-05-26 06:22:03 +00001560 ObjCMethodDecl *SMD = nullptr;
1561 if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
Richard Smitha0edd302014-05-31 00:18:32 +00001562 /*Property id*/ nullptr,
1563 SetterSel, S.Context))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001564 SMD = dyn_cast<ObjCMethodDecl>(SDecl);
Richard Smitha0edd302014-05-31 00:18:32 +00001565
1566 return new (S.Context)
1567 ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001568 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001569 }
1570 }
1571 // Use of id.member can only be for a property reference. Do not
1572 // use the 'id' redefinition in this case.
Richard Smitha0edd302014-05-31 00:18:32 +00001573 if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1574 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001575 ObjCImpDecl, HasTemplateArgs);
1576
Richard Smitha0edd302014-05-31 00:18:32 +00001577 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001578 << MemberName << BaseType);
1579 }
1580
1581 // 'Class', unqualified only.
1582 if (OT->isObjCClass()) {
1583 // Only works in a method declaration (??!).
Richard Smitha0edd302014-05-31 00:18:32 +00001584 ObjCMethodDecl *MD = S.getCurMethodDecl();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001585 if (!MD) {
Richard Smitha0edd302014-05-31 00:18:32 +00001586 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1587 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001588 ObjCImpDecl, HasTemplateArgs);
1589
1590 goto fail;
1591 }
1592
1593 // Also must look for a getter name which uses property syntax.
Richard Smitha0edd302014-05-31 00:18:32 +00001594 Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001595 ObjCInterfaceDecl *IFace = MD->getClassInterface();
1596 ObjCMethodDecl *Getter;
1597 if ((Getter = IFace->lookupClassMethod(Sel))) {
1598 // Check the use of this method.
Richard Smitha0edd302014-05-31 00:18:32 +00001599 if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001600 return ExprError();
1601 } else
1602 Getter = IFace->lookupPrivateMethod(Sel, false);
1603 // If we found a getter then this may be a valid dot-reference, we
1604 // will look for the matching setter, in case it is needed.
1605 Selector SetterSel =
Richard Smitha0edd302014-05-31 00:18:32 +00001606 SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1607 S.PP.getSelectorTable(),
Adrian Prantla4ce9062013-06-07 22:29:12 +00001608 Member);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001609 ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1610 if (!Setter) {
1611 // If this reference is in an @implementation, also check for 'private'
1612 // methods.
1613 Setter = IFace->lookupPrivateMethod(SetterSel, false);
1614 }
Douglas Gregor5476205b2011-06-23 00:49:38 +00001615
Richard Smitha0edd302014-05-31 00:18:32 +00001616 if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
Douglas Gregor5476205b2011-06-23 00:49:38 +00001617 return ExprError();
1618
1619 if (Getter || Setter) {
Richard Smitha0edd302014-05-31 00:18:32 +00001620 return new (S.Context) ObjCPropertyRefExpr(
1621 Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1622 OK_ObjCProperty, MemberLoc, BaseExpr.get());
Douglas Gregor5476205b2011-06-23 00:49:38 +00001623 }
1624
Richard Smitha0edd302014-05-31 00:18:32 +00001625 if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1626 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001627 ObjCImpDecl, HasTemplateArgs);
1628
Richard Smitha0edd302014-05-31 00:18:32 +00001629 return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
Douglas Gregor5476205b2011-06-23 00:49:38 +00001630 << MemberName << BaseType);
1631 }
1632
1633 // Normal property access.
Richard Smitha0edd302014-05-31 00:18:32 +00001634 return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
1635 MemberLoc, SourceLocation(), QualType(),
1636 false);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001637 }
1638
1639 // Handle 'field access' to vectors, such as 'V.xx'.
1640 if (BaseType->isExtVectorType()) {
1641 // FIXME: this expr should store IsArrow.
1642 IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
Fariborz Jahanian220d08d2015-04-06 16:56:39 +00001643 ExprValueKind VK;
1644 if (IsArrow)
1645 VK = VK_LValue;
1646 else {
1647 if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(BaseExpr.get()))
1648 VK = POE->getSyntacticForm()->getValueKind();
1649 else
1650 VK = BaseExpr.get()->getValueKind();
1651 }
Richard Smitha0edd302014-05-31 00:18:32 +00001652 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001653 Member, MemberLoc);
1654 if (ret.isNull())
1655 return ExprError();
1656
Richard Smitha0edd302014-05-31 00:18:32 +00001657 return new (S.Context)
Nikola Smiljanic03ff2592014-05-29 14:05:12 +00001658 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001659 }
1660
1661 // Adjust builtin-sel to the appropriate redefinition type if that's
1662 // not just a pointer to builtin-sel again.
Richard Smitha0edd302014-05-31 00:18:32 +00001663 if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
1664 !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
1665 BaseExpr = S.ImpCastExprToType(
1666 BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1667 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001668 ObjCImpDecl, HasTemplateArgs);
1669 }
1670
1671 // Failure cases.
1672 fail:
1673
1674 // Recover from dot accesses to pointers, e.g.:
1675 // type *foo;
1676 // foo.bar
1677 // This is actually well-formed in two cases:
1678 // - 'type' is an Objective C type
1679 // - 'bar' is a pseudo-destructor name which happens to refer to
1680 // the appropriate pointer type
1681 if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1682 if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
1683 MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
Richard Smitha0edd302014-05-31 00:18:32 +00001684 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1685 << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
Douglas Gregor5476205b2011-06-23 00:49:38 +00001686 << FixItHint::CreateReplacement(OpLoc, "->");
1687
1688 // Recurse as an -> access.
1689 IsArrow = true;
Richard Smitha0edd302014-05-31 00:18:32 +00001690 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001691 ObjCImpDecl, HasTemplateArgs);
1692 }
1693 }
1694
1695 // If the user is trying to apply -> or . to a function name, it's probably
1696 // because they forgot parentheses to call that function.
Richard Smitha0edd302014-05-31 00:18:32 +00001697 if (S.tryToRecoverWithCall(
1698 BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1699 /*complain*/ false,
1700 IsArrow ? &isPointerToRecordType : &isRecordType)) {
John McCall50a2c2c2011-10-11 23:14:30 +00001701 if (BaseExpr.isInvalid())
Douglas Gregor5476205b2011-06-23 00:49:38 +00001702 return ExprError();
Richard Smitha0edd302014-05-31 00:18:32 +00001703 BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1704 return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
John McCall50a2c2c2011-10-11 23:14:30 +00001705 ObjCImpDecl, HasTemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001706 }
1707
Richard Smitha0edd302014-05-31 00:18:32 +00001708 S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
Matt Beaumont-Gay025321b2012-04-21 02:13:04 +00001709 << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001710
1711 return ExprError();
1712}
1713
1714/// The main callback when the parser finds something like
1715/// expression . [nested-name-specifier] identifier
1716/// expression -> [nested-name-specifier] identifier
1717/// where 'identifier' encompasses a fairly broad spectrum of
1718/// possibilities, including destructor and operator references.
1719///
1720/// \param OpKind either tok::arrow or tok::period
James Dennett2a4d13c2012-06-15 07:13:21 +00001721/// \param ObjCImpDecl the current Objective-C \@implementation
1722/// decl; this is an ugly hack around the fact that Objective-C
1723/// \@implementations aren't properly put in the context chain
Douglas Gregor5476205b2011-06-23 00:49:38 +00001724ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
1725 SourceLocation OpLoc,
1726 tok::TokenKind OpKind,
1727 CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001728 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001729 UnqualifiedId &Id,
David Majnemerced8bdf2015-02-25 17:36:15 +00001730 Decl *ObjCImpDecl) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001731 if (SS.isSet() && SS.isInvalid())
1732 return ExprError();
1733
1734 // Warn about the explicit constructor calls Microsoft extension.
David Blaikiebbafb8a2012-03-11 07:00:24 +00001735 if (getLangOpts().MicrosoftExt &&
Douglas Gregor5476205b2011-06-23 00:49:38 +00001736 Id.getKind() == UnqualifiedId::IK_ConstructorName)
1737 Diag(Id.getSourceRange().getBegin(),
1738 diag::ext_ms_explicit_constructor_call);
1739
1740 TemplateArgumentListInfo TemplateArgsBuffer;
1741
1742 // Decompose the name into its component parts.
1743 DeclarationNameInfo NameInfo;
1744 const TemplateArgumentListInfo *TemplateArgs;
1745 DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1746 NameInfo, TemplateArgs);
1747
1748 DeclarationName Name = NameInfo.getName();
1749 bool IsArrow = (OpKind == tok::arrow);
1750
1751 NamedDecl *FirstQualifierInScope
Craig Topperc3ec1492014-05-26 06:22:03 +00001752 = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
Douglas Gregor5476205b2011-06-23 00:49:38 +00001753
1754 // This is a postfix expression, so get rid of ParenListExprs.
1755 ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
1756 if (Result.isInvalid()) return ExprError();
Nikola Smiljanic01a75982014-05-29 10:55:11 +00001757 Base = Result.get();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001758
1759 if (Base->getType()->isDependentType() || Name.isDependentName() ||
1760 isDependentScopeSpecifier(SS)) {
Richard Smitha0edd302014-05-31 00:18:32 +00001761 return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
1762 TemplateKWLoc, FirstQualifierInScope,
1763 NameInfo, TemplateArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001764 }
1765
David Majnemerced8bdf2015-02-25 17:36:15 +00001766 ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
Richard Smitha0edd302014-05-31 00:18:32 +00001767 return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS,
1768 TemplateKWLoc, FirstQualifierInScope,
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001769 NameInfo, TemplateArgs, S, &ExtraArgs);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001770}
1771
Richard Smith7873de02016-08-11 22:25:46 +00001772ExprResult
1773Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1774 SourceLocation OpLoc, const CXXScopeSpec &SS,
1775 FieldDecl *Field, DeclAccessPair FoundDecl,
1776 const DeclarationNameInfo &MemberNameInfo) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001777 // x.a is an l-value if 'a' has a reference type. Otherwise:
1778 // x.a is an l-value/x-value/pr-value if the base is (and note
1779 // that *x is always an l-value), except that if the base isn't
1780 // an ordinary object then we must have an rvalue.
1781 ExprValueKind VK = VK_LValue;
1782 ExprObjectKind OK = OK_Ordinary;
1783 if (!IsArrow) {
1784 if (BaseExpr->getObjectKind() == OK_Ordinary)
1785 VK = BaseExpr->getValueKind();
1786 else
1787 VK = VK_RValue;
1788 }
1789 if (VK != VK_RValue && Field->isBitField())
1790 OK = OK_BitField;
1791
1792 // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1793 QualType MemberType = Field->getType();
1794 if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1795 MemberType = Ref->getPointeeType();
1796 VK = VK_LValue;
1797 } else {
1798 QualType BaseType = BaseExpr->getType();
1799 if (IsArrow) BaseType = BaseType->getAs<PointerType>()->getPointeeType();
Matt Arsenault376f7202013-02-26 21:16:00 +00001800
Douglas Gregor5476205b2011-06-23 00:49:38 +00001801 Qualifiers BaseQuals = BaseType.getQualifiers();
Matt Arsenault376f7202013-02-26 21:16:00 +00001802
Douglas Gregor5476205b2011-06-23 00:49:38 +00001803 // GC attributes are never picked up by members.
1804 BaseQuals.removeObjCGCAttr();
Matt Arsenault376f7202013-02-26 21:16:00 +00001805
Douglas Gregor5476205b2011-06-23 00:49:38 +00001806 // CVR attributes from the base are picked up by members,
1807 // except that 'mutable' members don't pick up 'const'.
1808 if (Field->isMutable()) BaseQuals.removeConst();
Matt Arsenault376f7202013-02-26 21:16:00 +00001809
Richard Smith7873de02016-08-11 22:25:46 +00001810 Qualifiers MemberQuals =
1811 Context.getCanonicalType(MemberType).getQualifiers();
Matt Arsenault376f7202013-02-26 21:16:00 +00001812
Douglas Gregor5476205b2011-06-23 00:49:38 +00001813 assert(!MemberQuals.hasAddressSpace());
Matt Arsenault376f7202013-02-26 21:16:00 +00001814
Douglas Gregor5476205b2011-06-23 00:49:38 +00001815 Qualifiers Combined = BaseQuals + MemberQuals;
1816 if (Combined != MemberQuals)
Richard Smith7873de02016-08-11 22:25:46 +00001817 MemberType = Context.getQualifiedType(MemberType, Combined);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001818 }
Matt Arsenault376f7202013-02-26 21:16:00 +00001819
Richard Smith7873de02016-08-11 22:25:46 +00001820 UnusedPrivateFields.remove(Field);
Daniel Jasper0baec5492012-06-06 08:32:04 +00001821
Richard Smith7873de02016-08-11 22:25:46 +00001822 ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
1823 FoundDecl, Field);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001824 if (Base.isInvalid())
1825 return ExprError();
Alexey Bataev90c228f2016-02-08 09:29:13 +00001826 MemberExpr *ME =
Richard Smith7873de02016-08-11 22:25:46 +00001827 BuildMemberExpr(*this, Context, Base.get(), IsArrow, OpLoc, SS,
Alexey Bataev90c228f2016-02-08 09:29:13 +00001828 /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1829 MemberNameInfo, MemberType, VK, OK);
1830
1831 // Build a reference to a private copy for non-static data members in
1832 // non-static member functions, privatized by OpenMP constructs.
Richard Smith7873de02016-08-11 22:25:46 +00001833 if (getLangOpts().OpenMP && IsArrow &&
1834 !CurContext->isDependentContext() &&
Alexey Bataev90c228f2016-02-08 09:29:13 +00001835 isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
Richard Smith7873de02016-08-11 22:25:46 +00001836 if (auto *PrivateCopy = IsOpenMPCapturedDecl(Field))
1837 return getOpenMPCapturedExpr(PrivateCopy, VK, OK, OpLoc);
Alexey Bataev90c228f2016-02-08 09:29:13 +00001838 }
1839 return ME;
Douglas Gregor5476205b2011-06-23 00:49:38 +00001840}
1841
1842/// Builds an implicit member access expression. The current context
1843/// is known to be an instance method, and the given unqualified lookup
1844/// set is known to contain only instance members, at least one of which
1845/// is from an appropriate type.
1846ExprResult
1847Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001848 SourceLocation TemplateKWLoc,
Douglas Gregor5476205b2011-06-23 00:49:38 +00001849 LookupResult &R,
1850 const TemplateArgumentListInfo *TemplateArgs,
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001851 bool IsKnownInstance, const Scope *S) {
Douglas Gregor5476205b2011-06-23 00:49:38 +00001852 assert(!R.empty() && !R.isAmbiguous());
1853
1854 SourceLocation loc = R.getNameLoc();
Richard Smith59d26d22014-01-17 22:29:43 +00001855
Douglas Gregor5476205b2011-06-23 00:49:38 +00001856 // If this is known to be an instance access, go ahead and build an
1857 // implicit 'this' expression now.
1858 // 'this' expression now.
Douglas Gregor09deffa2011-10-18 16:47:30 +00001859 QualType ThisTy = getCurrentThisType();
Douglas Gregor5476205b2011-06-23 00:49:38 +00001860 assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
Craig Topperc3ec1492014-05-26 06:22:03 +00001861
1862 Expr *baseExpr = nullptr; // null signifies implicit access
Douglas Gregor5476205b2011-06-23 00:49:38 +00001863 if (IsKnownInstance) {
1864 SourceLocation Loc = R.getNameLoc();
1865 if (SS.getRange().isValid())
1866 Loc = SS.getRange().getBegin();
Eli Friedman73a04092012-01-07 04:59:52 +00001867 CheckCXXThisCapture(Loc);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001868 baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true);
1869 }
Craig Topperc3ec1492014-05-26 06:22:03 +00001870
Douglas Gregor5476205b2011-06-23 00:49:38 +00001871 return BuildMemberReferenceExpr(baseExpr, ThisTy,
1872 /*OpLoc*/ SourceLocation(),
1873 /*IsArrow*/ true,
Abramo Bagnara7945c982012-01-27 09:46:47 +00001874 SS, TemplateKWLoc,
Craig Topperc3ec1492014-05-26 06:22:03 +00001875 /*FirstQualifierInScope*/ nullptr,
Aaron Ballman6924dcd2015-09-01 14:49:24 +00001876 R, TemplateArgs, S);
Douglas Gregor5476205b2011-06-23 00:49:38 +00001877}