Coverage Report

Created: 2022-01-18 06:27

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