Coverage Report

Created: 2022-05-17 06:19

/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
724k
                                     const BaseSet &Bases) {
34
731k
  auto BaseIsNotInSet = [&Bases](const CXXRecordDecl *Base) {
35
731k
    return !Bases.count(Base->getCanonicalDecl());
36
731k
  };
37
724k
  return BaseIsNotInSet(Record) && 
Record->forallBases(BaseIsNotInSet)6.79k
;
38
724k
}
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.76M
                                            const LookupResult &R) {
90
1.76M
  assert(!R.empty() && (*R.begin())->isCXXClassMember());
91
92
0
  DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
93
94
1.76M
  bool isStaticContext = SemaRef.CXXThisTypeOverride.isNull() &&
95
1.76M
    
(1.76M
!isa<CXXMethodDecl>(DC)1.76M
||
cast<CXXMethodDecl>(DC)->isStatic()984k
);
96
97
1.76M
  if (R.isUnresolvableResult())
98
97
    return isStaticContext ? 
IMA_Unresolved_StaticContext39
:
IMA_Unresolved58
;
99
100
  // Collect all the declaring classes of instance members we find.
101
1.76M
  bool hasNonInstance = false;
102
1.76M
  bool isField = false;
103
1.76M
  BaseSet Classes;
104
2.15M
  for (NamedDecl *D : R) {
105
    // Look through any using decls.
106
2.15M
    D = D->getUnderlyingDecl();
107
108
2.15M
    if (D->isCXXInstanceMember()) {
109
1.09M
      isField |= isa<FieldDecl>(D) || 
isa<MSPropertyDecl>(D)738k
||
110
1.09M
                 
isa<IndirectFieldDecl>(D)738k
;
111
112
1.09M
      CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
113
1.09M
      Classes.insert(R->getCanonicalDecl());
114
1.09M
    } else
115
1.06M
      hasNonInstance = true;
116
2.15M
  }
117
118
  // If we didn't find any instance members, it can't be an implicit
119
  // member reference.
120
1.76M
  if (Classes.empty())
121
1.04M
    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
724k
  IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false'
133
724k
  assert(!AbstractInstanceResult);
134
0
  switch (SemaRef.ExprEvalContexts.back().Context) {
135
3.00k
  case Sema::ExpressionEvaluationContext::Unevaluated:
136
3.00k
  case Sema::ExpressionEvaluationContext::UnevaluatedList:
137
3.00k
    if (isField && 
SemaRef.getLangOpts().CPlusPlus112.90k
)
138
2.84k
      AbstractInstanceResult = IMA_Field_Uneval_Context;
139
3.00k
    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
721k
  case Sema::ExpressionEvaluationContext::PotentiallyEvaluated:
149
721k
  case Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
150
721k
    break;
151
724k
  }
152
153
  // If the current context is not an instance method, it can't be
154
  // an implicit member reference.
155
724k
  if (isStaticContext) {
156
695
    if (hasNonInstance)
157
311
      return IMA_Mixed_StaticContext;
158
159
384
    return AbstractInstanceResult ? 
AbstractInstanceResult301
160
384
                                  : 
IMA_Error_StaticContext83
;
161
695
  }
162
163
724k
  CXXRecordDecl *contextClass;
164
724k
  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
165
722k
    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
724k
  if (R.getNamingClass() &&
176
724k
      contextClass->getCanonicalDecl() !=
177
724k
        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
4.59k
    Classes.clear();
182
4.59k
    Classes.insert(R.getNamingClass()->getCanonicalDecl());
183
4.59k
  }
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
724k
  if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
189
36
    return hasNonInstance ? 
IMA_Mixed_Unrelated9
:
190
36
           
AbstractInstanceResult27
?
AbstractInstanceResult8
:
191
27
                                    
IMA_Error_Unrelated19
;
192
193
724k
  return (hasNonInstance ? 
IMA_Mixed1.59k
:
IMA_Instance722k
);
194
724k
}
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.76M
    UnresolvedLookupExpr *AsULE) {
239
1.76M
  switch (ClassifyImplicitMemberAccess(*this, R)) {
240
722k
  case IMA_Instance:
241
722k
    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
303
  case IMA_Field_Uneval_Context:
250
303
    Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
251
303
      << R.getLookupNameInfo().getName();
252
303
    LLVM_FALLTHROUGH;
253
1.04M
  case IMA_Static:
254
1.04M
  case IMA_Abstract:
255
1.04M
  case IMA_Mixed_StaticContext:
256
1.04M
  case IMA_Unresolved_StaticContext:
257
1.04M
    if (TemplateArgs || 
TemplateKWLoc.isValid()1.03M
)
258
9.41k
      return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
259
1.03M
    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.76M
  }
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.15k
IsRGBA(char c) {
274
1.15k
  switch (c) {
275
78
  case 'r':
276
118
  case 'g':
277
153
  case 'b':
278
175
  case 'a':
279
175
    return true;
280
975
  default:
281
975
    return false;
282
1.15k
  }
283
1.15k
}
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
523
                        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
523
  const ExtVectorType *vecType = baseType->getAs<ExtVectorType>();
307
308
  // The vector accessor can't exceed the number of elements.
309
523
  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
523
  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
523
  bool HexSwizzle = (*compStr == 's' || 
*compStr == 'S'494
) &&
compStr[1]30
;
319
320
523
  bool HasRepeated = false;
321
523
  bool HasIndex[16] = {};
322
323
523
  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
523
  if (!strcmp(compStr, "hi") || 
!strcmp(compStr, "lo")509
||
328
523
      
!strcmp(compStr, "even")491
||
!strcmp(compStr, "odd")479
) {
329
46
    HalvingSwizzle = true;
330
477
  } else if (!HexSwizzle &&
331
477
             
(Idx = vecType->getPointAccessorIdx(*compStr)) != -1453
) {
332
447
    bool HasRGBA = IsRGBA(*compStr);
333
696
    do {
334
      // Ensure that xyzw and rgba components don't intermingle.
335
696
      if (HasRGBA != IsRGBA(*compStr))
336
7
        break;
337
689
      if (HasIndex[Idx]) 
HasRepeated = true33
;
338
689
      HasIndex[Idx] = true;
339
689
      compStr++;
340
689
    } 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
447
    if (HasRGBA || 
(401
*compStr401
&&
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
447
  } 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
523
  if (!HalvingSwizzle && 
*compStr477
) {
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
507
  if (!HalvingSwizzle) {
371
461
    compStr = CompName->getNameStart();
372
373
461
    if (HexSwizzle)
374
23
      compStr++;
375
376
1.15k
    while (*compStr) {
377
699
      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
699
    }
383
461
  }
384
385
  // OpenCL mode requires swizzle length to be in accordance with accepted
386
  // sizes. Clang however supports arbitrary lengths for other languages.
387
498
  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
496
  unsigned CompSize = HalvingSwizzle ? 
(vecType->getNumElements() + 1) / 246
406
496
                                     : 
CompName->getLength()450
;
407
496
  if (HexSwizzle)
408
20
    CompSize--;
409
410
496
  if (CompSize == 1)
411
346
    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
777k
                               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
777k
  if (!IsArrow) {
497
611k
    const PointerType *PT = BaseType->getAs<PointerType>();
498
611k
    if (PT && 
(10
!getLangOpts().ObjC10
||
499
10
               
PT->getPointeeType()->isRecordType()4
)) {
500
6
      assert(BaseExpr && "cannot happen with implicit member accesses");
501
0
      Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
502
6
        << BaseType << BaseExpr->getSourceRange() << NameInfo.getSourceRange();
503
6
      return ExprError();
504
6
    }
505
611k
  }
506
507
777k
  assert(BaseType->isDependentType() || NameInfo.getName().isDependentName() ||
508
777k
         isDependentScopeSpecifier(SS) ||
509
777k
         (TemplateArgs && llvm::any_of(TemplateArgs->arguments(),
510
777k
                                       [](const TemplateArgumentLoc &Arg) {
511
777k
                                         return Arg.getArgument().isDependent();
512
777k
                                       })));
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
777k
      Context, BaseExpr, BaseType, IsArrow, OpLoc,
518
777k
      SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
519
777k
      NameInfo, TemplateArgs);
520
777k
}
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
829k
                                         const LookupResult &R) {
556
829k
  CXXRecordDecl *BaseRecord =
557
829k
    cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType));
558
829k
  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
829k
  
for (LookupResult::iterator I = R.begin(), E = R.end(); 829k
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
829k
    if (!BaseExpr && 
!(*I)->isCXXInstanceMember()34.1k
)
569
14.8k
      return false;
570
571
    // Note that we use the DC of the decl, not the underlying decl.
572
814k
    DeclContext *DC = (*I)->getDeclContext()->getNonTransparentContext();
573
814k
    if (!DC->isRecord())
574
3
      continue;
575
576
814k
    CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
577
814k
    if (BaseRecord->getCanonicalDecl() == MemberRecord ||
578
814k
        
!BaseRecord->isProvablyNotDerivedFrom(MemberRecord)10.2k
)
579
814k
      return false;
580
814k
  }
581
582
26
  DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS,
583
26
                                   R.getRepresentativeDecl(),
584
26
                                   R.getLookupNameInfo());
585
26
  return true;
586
829k
}
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
530
      : 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
530
    WantTypeSpecifiers = false;
600
530
    WantExpressionKeywords = false;
601
530
    WantCXXNamedCasts = false;
602
530
    WantFunctionLikeCasts = false;
603
530
    WantRemainingKeywords = false;
604
530
  }
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
536k
                                     TypoExpr *&TE) {
647
536k
  SourceRange BaseRange = BaseExpr ? 
BaseExpr->getSourceRange()519k
:
SourceRange()17.2k
;
648
536k
  RecordDecl *RDecl = RTy->getDecl();
649
536k
  if (!SemaRef.isThisOutsideMemberFunctionBody(QualType(RTy, 0)) &&
650
536k
      SemaRef.RequireCompleteType(OpLoc, QualType(RTy, 0),
651
536k
                                  diag::err_typecheck_incomplete_tag,
652
536k
                                  BaseRange))
653
3
    return true;
654
655
536k
  if (HasTemplateArgs || 
TemplateKWLoc.isValid()533k
) {
656
    // LookupTemplateName doesn't expect these both to exist simultaneously.
657
2.55k
    QualType ObjectType = SS.isSet() ? 
QualType()68
:
QualType(RTy, 0)2.48k
;
658
659
2.55k
    bool MOUS;
660
2.55k
    return SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS,
661
2.55k
                                      TemplateKWLoc);
662
2.55k
  }
663
664
533k
  DeclContext *DC = RDecl;
665
533k
  if (SS.isSet()) {
666
    // If the member name was a qualified-id, look into the
667
    // nested-name-specifier.
668
17.8k
    DC = SemaRef.computeDeclContext(SS, false);
669
670
17.8k
    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
17.8k
    assert(DC && "Cannot handle non-computable dependent contexts in lookup");
677
678
17.8k
    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
17.8k
  }
684
685
  // The record definition is complete, now look up the member.
686
533k
  SemaRef.LookupQualifiedName(R, DC, SS);
687
688
533k
  if (!R.empty())
689
533k
    return false;
690
691
530
  DeclarationName Typo = R.getLookupName();
692
530
  SourceLocation TypoLoc = R.getNameLoc();
693
694
530
  struct QueryState {
695
530
    Sema &SemaRef;
696
530
    DeclarationNameInfo NameInfo;
697
530
    Sema::LookupNameKind LookupKind;
698
530
    Sema::RedeclarationKind Redecl;
699
530
  };
700
530
  QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
701
530
                  R.redeclarationKind()};
702
530
  RecordMemberExprValidatorCCC CCC(RTy);
703
530
  TE = SemaRef.CorrectTypoDelayed(
704
530
      R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC,
705
530
      [=, &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
530
      [=](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
530
      Sema::CTK_ErrorRecovery, DC);
732
733
530
  return false;
734
533k
}
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
543k
                               ActOnMemberAccessExtraArgs *ExtraArgs) {
752
543k
  if (BaseType->isDependentType() ||
753
543k
      
(540k
SS.isSet()540k
&&
isDependentScopeSpecifier(SS)17.9k
))
754
3.44k
    return ActOnDependentMemberExpr(Base, BaseType,
755
3.44k
                                    IsArrow, OpLoc,
756
3.44k
                                    SS, TemplateKWLoc, FirstQualifierInScope,
757
3.44k
                                    NameInfo, TemplateArgs);
758
759
540k
  LookupResult R(*this, NameInfo, LookupMemberName);
760
761
  // Implicit member accesses.
762
540k
  if (!Base) {
763
17.2k
    TypoExpr *TE = nullptr;
764
17.2k
    QualType RecordTy = BaseType;
765
17.2k
    if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType();
766
17.2k
    if (LookupMemberExprInRecord(
767
17.2k
            *this, R, nullptr, RecordTy->getAs<RecordType>(), OpLoc, IsArrow,
768
17.2k
            SS, TemplateArgs != nullptr, TemplateKWLoc, TE))
769
6
      return ExprError();
770
17.2k
    if (TE)
771
0
      return TE;
772
773
  // Explicit member accesses.
774
523k
  } else {
775
523k
    ExprResult BaseResult = Base;
776
523k
    ExprResult Result =
777
523k
        LookupMemberExpr(*this, R, BaseResult, IsArrow, OpLoc, SS,
778
523k
                         ExtraArgs ? 
ExtraArgs->ObjCImpDecl402k
:
nullptr120k
,
779
523k
                         TemplateArgs != nullptr, TemplateKWLoc);
780
781
523k
    if (BaseResult.isInvalid())
782
1
      return ExprError();
783
523k
    Base = BaseResult.get();
784
785
523k
    if (Result.isInvalid())
786
201
      return ExprError();
787
788
522k
    if (Result.get())
789
3.91k
      return Result;
790
791
    // LookupMemberExpr can modify Base, and thus change BaseType
792
518k
    BaseType = Base->getType();
793
518k
  }
794
795
536k
  return BuildMemberReferenceExpr(Base, BaseType,
796
536k
                                  OpLoc, IsArrow, SS, TemplateKWLoc,
797
536k
                                  FirstQualifierInScope, R, TemplateArgs, S,
798
536k
                                  false, ExtraArgs);
799
540k
}
800
801
ExprResult
802
Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
803
                                               SourceLocation loc,
804
                                               IndirectFieldDecl *indirectField,
805
                                               DeclAccessPair foundDecl,
806
                                               Expr *baseObjectExpr,
807
5.48k
                                               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.48k
  VarDecl *baseVariable = indirectField->getVarDecl();
812
5.48k
  CXXScopeSpec EmptySS;
813
5.48k
  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.48k
  assert((baseVariable || baseObjectExpr) &&
833
5.48k
         "referencing anonymous struct/union without a base variable or "
834
5.48k
         "expression");
835
836
  // Build the implicit member references to the field of the
837
  // anonymous struct/union.
838
0
  Expr *result = baseObjectExpr;
839
5.48k
  IndirectFieldDecl::chain_iterator
840
5.48k
  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.48k
  if (!baseVariable) {
845
5.41k
    FieldDecl *field = cast<FieldDecl>(*FI);
846
847
5.41k
    bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType();
848
849
    // Make a nameInfo that properly uses the anonymous name.
850
5.41k
    DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
851
852
    // Build the first member access in the chain with full information.
853
5.41k
    result =
854
5.41k
        BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(),
855
5.41k
                                SS, field, foundDecl, memberNameInfo)
856
5.41k
            .get();
857
5.41k
    if (!result)
858
0
      return ExprError();
859
5.41k
  }
860
861
  // In all cases, we should now skip the first declaration in the chain.
862
5.48k
  ++FI;
863
864
11.1k
  while (FI != FEnd) {
865
5.64k
    FieldDecl *field = cast<FieldDecl>(*FI++);
866
867
    // FIXME: these are somewhat meaningless
868
5.64k
    DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
869
5.64k
    DeclAccessPair fakeFoundDecl =
870
5.64k
        DeclAccessPair::make(field, field->getAccess());
871
872
5.64k
    result =
873
5.64k
        BuildFieldReferenceExpr(result, /*isarrow*/ false, SourceLocation(),
874
5.64k
                                (FI == FEnd ? 
SS5.48k
:
EmptySS156
), field,
875
5.64k
                                fakeFoundDecl, memberNameInfo)
876
5.64k
            .get();
877
5.64k
  }
878
879
5.48k
  return result;
880
5.48k
}
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.14M
    const TemplateArgumentListInfo *TemplateArgs) {
901
1.14M
  NestedNameSpecifierLoc NNS =
902
1.14M
      SS ? SS->getWithLocInContext(Context) : 
NestedNameSpecifierLoc()0
;
903
1.14M
  return BuildMemberExpr(Base, IsArrow, OpLoc, NNS, TemplateKWLoc, Member,
904
1.14M
                         FoundDecl, HadMultipleCandidates, MemberNameInfo, Ty,
905
1.14M
                         VK, OK, TemplateArgs);
906
1.14M
}
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.22M
    const TemplateArgumentListInfo *TemplateArgs) {
914
1.22M
  assert((!IsArrow || Base->isPRValue()) &&
915
1.22M
         "-> base must be a pointer prvalue");
916
0
  MemberExpr *E =
917
1.22M
      MemberExpr::Create(Context, Base, IsArrow, OpLoc, NNS, TemplateKWLoc,
918
1.22M
                         Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty,
919
1.22M
                         VK, OK, getNonOdrUseReasonInCurrentContext(Member));
920
1.22M
  E->setHadMultipleCandidates(HadMultipleCandidates);
921
1.22M
  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.22M
  if (auto *FPT = Ty->getAs<FunctionProtoType>()) {
928
730
    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
730
  }
933
934
1.22M
  return E;
935
1.22M
}
936
937
/// Determine if the given scope is within a function-try-block handler.
938
82.7k
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
186k
  for (; S != S->getFnParent(); 
S = S->getParent()104k
) {
943
104k
    if (S->isFnTryCatchScope())
944
10
      return (S->getFlags() & Scope::TryScope) != Scope::TryScope;
945
104k
  }
946
82.7k
  return false;
947
82.7k
}
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.40M
                               ActOnMemberAccessExtraArgs *ExtraArgs) {
960
1.40M
  QualType BaseType = BaseExprType;
961
1.40M
  if (IsArrow) {
962
1.00M
    assert(BaseType->isPointerType());
963
0
    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
964
1.00M
  }
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.40M
  if (!IsArrow && 
BaseExpr396k
&&
BaseExpr->isPRValue()396k
) {
970
12.4k
    ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
971
12.4k
    if (Converted.isInvalid())
972
0
      return ExprError();
973
12.4k
    BaseExpr = Converted.get();
974
12.4k
  }
975
976
1.40M
  const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
977
1.40M
  DeclarationName MemberName = MemberNameInfo.getName();
978
1.40M
  SourceLocation MemberLoc = MemberNameInfo.getLoc();
979
980
1.40M
  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.40M
  const auto *FD = getCurFunctionDecl();
987
1.40M
  if (S && 
BaseExpr1.12M
&&
FD1.12M
&&
988
1.40M
      
(1.11M
isa<CXXDestructorDecl>(FD)1.11M
||
isa<CXXConstructorDecl>(FD)1.09M
) &&
989
1.40M
      
isa<CXXThisExpr>(BaseExpr->IgnoreImpCasts())95.1k
&&
990
1.40M
      
IsInFnTryBlockHandler(S)82.7k
)
991
10
    Diag(MemberLoc, diag::warn_cdtor_function_try_handler_mem_expr)
992
10
        << isa<CXXDestructorDecl>(FD);
993
994
1.40M
  if (R.empty()) {
995
    // Rederive where we looked up.
996
392
    DeclContext *DC = (SS.isSet()
997
392
                       ? 
computeDeclContext(SS, false)15
998
392
                       : 
BaseType->castAs<RecordType>()->getDecl()377
);
999
1000
392
    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
385
    Diag(R.getNameLoc(), diag::err_no_member)
1026
385
      << MemberName << DC
1027
385
      << (BaseExpr ? 
BaseExpr->getSourceRange()374
:
SourceRange()11
);
1028
385
    return ExprError();
1029
392
  }
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.39M
  if ((SS.isSet() || 
!BaseExpr1.37M
||
1039
1.39M
       
(1.35M
isa<CXXThisExpr>(BaseExpr)1.35M
&&
1040
1.35M
        
cast<CXXThisExpr>(BaseExpr)->isImplicit()807k
)) &&
1041
1.39M
      
!SuppressQualifierCheck831k
&&
1042
1.39M
      
CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R)829k
)
1043
26
    return ExprError();
1044
1045
  // Construct an unresolved result if we in fact got an unresolved
1046
  // result.
1047
1.39M
  if (R.isOverloadedResult() || 
R.isUnresolvableResult()1.14M
) {
1048
    // Suppress any lookup-related diagnostics; we'll do these when we
1049
    // pick a member.
1050
250k
    R.suppressDiagnostics();
1051
1052
250k
    UnresolvedMemberExpr *MemExpr
1053
250k
      = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(),
1054
250k
                                     BaseExpr, BaseExprType,
1055
250k
                                     IsArrow, OpLoc,
1056
250k
                                     SS.getWithLocInContext(Context),
1057
250k
                                     TemplateKWLoc, MemberNameInfo,
1058
250k
                                     TemplateArgs, R.begin(), R.end());
1059
1060
250k
    return MemExpr;
1061
250k
  }
1062
1063
1.14M
  assert(R.isSingleResult());
1064
0
  DeclAccessPair FoundDecl = R.begin().getPair();
1065
1.14M
  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.14M
  if (MemberDecl->isInvalidDecl())
1073
88
    return ExprError();
1074
1075
  // Handle the implicit-member-access case.
1076
1.14M
  if (!BaseExpr) {
1077
    // If this is not an instance member, convert to a non-member access.
1078
11.4k
    if (!MemberDecl->isCXXInstanceMember()) {
1079
      // We might have a variable template specialization (or maybe one day a
1080
      // member concept-id).
1081
9.10k
      if (TemplateArgs || 
TemplateKWLoc.isValid()9.10k
)
1082
1
        return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/false, TemplateArgs);
1083
1084
9.10k
      return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl,
1085
9.10k
                                      FoundDecl, TemplateArgs);
1086
9.10k
    }
1087
2.37k
    SourceLocation Loc = R.getNameLoc();
1088
2.37k
    if (SS.getRange().isValid())
1089
2.33k
      Loc = SS.getRange().getBegin();
1090
2.37k
    BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
1091
2.37k
  }
1092
1093
  // Check the use of this member.
1094
1.14M
  if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
1095
33
    return ExprError();
1096
1097
1.14M
  if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
1098
820k
    return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
1099
820k
                                   MemberNameInfo);
1100
1101
319k
  if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
1102
223
    return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
1103
223
                                  MemberNameInfo);
1104
1105
319k
  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.41k
    return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
1109
5.41k
                                                    FoundDecl, BaseExpr,
1110
5.41k
                                                    OpLoc);
1111
1112
314k
  if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
1113
430
    return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc, Var,
1114
430
                           FoundDecl, /*HadMultipleCandidates=*/false,
1115
430
                           MemberNameInfo, Var->getType().getNonReferenceType(),
1116
430
                           VK_LValue, OK_Ordinary);
1117
430
  }
1118
1119
313k
  if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
1120
313k
    ExprValueKind valueKind;
1121
313k
    QualType type;
1122
313k
    if (MemberFn->isInstance()) {
1123
313k
      valueKind = VK_PRValue;
1124
313k
      type = Context.BoundMemberTy;
1125
313k
    } else {
1126
281
      valueKind = VK_LValue;
1127
281
      type = MemberFn->getType();
1128
281
    }
1129
1130
313k
    return BuildMemberExpr(BaseExpr, IsArrow, OpLoc, &SS, TemplateKWLoc,
1131
313k
                           MemberFn, FoundDecl, /*HadMultipleCandidates=*/false,
1132
313k
                           MemberNameInfo, type, valueKind, OK_Ordinary);
1133
313k
  }
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
599k
Sema::PerformMemberExprBaseConversion(Expr *Base, bool IsArrow) {
1228
599k
  if (IsArrow && 
!Base->getType()->isFunctionType()242k
)
1229
242k
    return DefaultFunctionArrayLvalueConversion(Base);
1230
1231
356k
  return CheckPlaceholderExpr(Base);
1232
599k
}
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
523k
                                   SourceLocation TemplateKWLoc) {
1249
523k
  assert(BaseExpr.get() && "no base expression");
1250
1251
  // Perform default conversions.
1252
0
  BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
1253
523k
  if (BaseExpr.isInvalid())
1254
1
    return ExprError();
1255
1256
523k
  QualType BaseType = BaseExpr.get()->getType();
1257
523k
  assert(!BaseType->isDependentType());
1258
1259
0
  DeclarationName MemberName = R.getLookupName();
1260
523k
  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
523k
  if (IsArrow) {
1267
169k
    if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1268
168k
      BaseType = Ptr->getPointeeType();
1269
1.14k
    else if (const ObjCObjectPointerType *Ptr
1270
1.14k
               = BaseType->getAs<ObjCObjectPointerType>())
1271
1.10k
      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
169k
  }
1294
1295
  // If the base type is an atomic type, this access is undefined behavior per
1296
  // C11 6.5.2.3p5. Instead of giving a typecheck error, we'll warn the user
1297
  // about the UB and recover by converting the atomic lvalue into a non-atomic
1298
  // lvalue. Because this is inherently unsafe as an atomic operation, the
1299
  // warning defaults to an error.
1300
523k
  if (const auto *ATy = BaseType->getAs<AtomicType>()) {
1301
28
    S.DiagRuntimeBehavior(OpLoc, nullptr,
1302
28
                          S.PDiag(diag::warn_atomic_member_access));
1303
28
    BaseType = ATy->getValueType().getUnqualifiedType();
1304
28
    BaseExpr = ImplicitCastExpr::Create(
1305
28
        S.Context, IsArrow ? 
S.Context.getPointerType(BaseType)12
:
BaseType16
,
1306
28
        CK_AtomicToNonAtomic, BaseExpr.get(), nullptr,
1307
28
        BaseExpr.get()->getValueKind(), FPOptionsOverride());
1308
28
  }
1309
1310
  // Handle field access to simple records.
1311
523k
  if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
1312
519k
    TypoExpr *TE = nullptr;
1313
519k
    if (LookupMemberExprInRecord(S, R, BaseExpr.get(), RTy, OpLoc, IsArrow, SS,
1314
519k
                                 HasTemplateArgs, TemplateKWLoc, TE))
1315
22
      return ExprError();
1316
1317
    // Returning valid-but-null is how we indicate to the caller that
1318
    // the lookup result was filled in. If typo correction was attempted and
1319
    // failed, the lookup result will have been cleared--that combined with the
1320
    // valid-but-null ExprResult will trigger the appropriate diagnostics.
1321
519k
    return ExprResult(TE);
1322
519k
  }
1323
1324
  // Handle ivar access to Objective-C objects.
1325
4.00k
  if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
1326
1.13k
    if (!SS.isEmpty() && 
!SS.isInvalid()2
) {
1327
1
      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1328
1
        << 1 << SS.getScopeRep()
1329
1
        << FixItHint::CreateRemoval(SS.getRange());
1330
1
      SS.clear();
1331
1
    }
1332
1333
1.13k
    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1334
1335
    // There are three cases for the base type:
1336
    //   - builtin id (qualified or unqualified)
1337
    //   - builtin Class (qualified or unqualified)
1338
    //   - an interface
1339
1.13k
    ObjCInterfaceDecl *IDecl = OTy->getInterface();
1340
1.13k
    if (!IDecl) {
1341
74
      if (S.getLangOpts().ObjCAutoRefCount &&
1342
74
          
(8
OTy->isObjCId()8
||
OTy->isObjCClass()4
))
1343
8
        goto fail;
1344
      // There's an implicit 'isa' ivar on all objects.
1345
      // But we only actually find it this way on objects of type 'id',
1346
      // apparently.
1347
66
      if (OTy->isObjCId() && 
Member->isStr("isa")64
)
1348
62
        return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
1349
62
                                           OpLoc, S.Context.getObjCClassType());
1350
4
      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1351
3
        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1352
3
                                ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1353
1
      goto fail;
1354
4
    }
1355
1356
1.06k
    if (S.RequireCompleteType(OpLoc, BaseType,
1357
1.06k
                              diag::err_typecheck_incomplete_tag,
1358
1.06k
                              BaseExpr.get()))
1359
0
      return ExprError();
1360
1361
1.06k
    ObjCInterfaceDecl *ClassDeclared = nullptr;
1362
1.06k
    ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
1363
1364
1.06k
    if (!IV) {
1365
      // Attempt to correct for typos in ivar names.
1366
24
      DeclFilterCCC<ObjCIvarDecl> Validator{};
1367
24
      Validator.IsObjCIvarLookup = IsArrow;
1368
24
      if (TypoCorrection Corrected = S.CorrectTypo(
1369
24
              R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
1370
24
              Validator, Sema::CTK_ErrorRecovery, IDecl)) {
1371
9
        IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
1372
9
        S.diagnoseTypo(
1373
9
            Corrected,
1374
9
            S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
1375
9
                << IDecl->getDeclName() << MemberName);
1376
1377
        // Figure out the class that declares the ivar.
1378
9
        assert(!ClassDeclared);
1379
1380
0
        Decl *D = cast<Decl>(IV->getDeclContext());
1381
9
        if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
1382
1
          D = Category->getClassInterface();
1383
1384
9
        if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
1385
1
          ClassDeclared = Implementation->getClassInterface();
1386
8
        else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
1387
8
          ClassDeclared = Interface;
1388
1389
9
        assert(ClassDeclared && "cannot query interface");
1390
15
      } else {
1391
15
        if (IsArrow &&
1392
15
            IDecl->FindPropertyDeclaration(
1393
15
                Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
1394
2
          S.Diag(MemberLoc, diag::err_property_found_suggest)
1395
2
              << Member << BaseExpr.get()->getType()
1396
2
              << FixItHint::CreateReplacement(OpLoc, ".");
1397
2
          return ExprError();
1398
2
        }
1399
1400
13
        S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
1401
13
            << IDecl->getDeclName() << MemberName
1402
13
            << BaseExpr.get()->getSourceRange();
1403
13
        return ExprError();
1404
15
      }
1405
24
    }
1406
1407
1.04k
    assert(ClassDeclared);
1408
1409
    // If the decl being referenced had an error, return an error for this
1410
    // sub-expr without emitting another error, in order to avoid cascading
1411
    // error cases.
1412
1.04k
    if (IV->isInvalidDecl())
1413
0
      return ExprError();
1414
1415
    // Check whether we can reference this field.
1416
1.04k
    if (S.DiagnoseUseOfDecl(IV, MemberLoc))
1417
0
      return ExprError();
1418
1.04k
    if (IV->getAccessControl() != ObjCIvarDecl::Public &&
1419
1.04k
        
IV->getAccessControl() != ObjCIvarDecl::Package521
) {
1420
511
      ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1421
511
      if (ObjCMethodDecl *MD = S.getCurMethodDecl())
1422
468
        ClassOfMethodDecl =  MD->getClassInterface();
1423
43
      else if (ObjCImpDecl && 
S.getCurFunctionDecl()23
) {
1424
        // Case of a c-function declared inside an objc implementation.
1425
        // FIXME: For a c-style function nested inside an objc implementation
1426
        // class, there is no implementation context available, so we pass
1427
        // down the context as argument to this routine. Ideally, this context
1428
        // need be passed down in the AST node and somehow calculated from the
1429
        // AST for a function decl.
1430
23
        if (ObjCImplementationDecl *IMPD =
1431
23
              dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
1432
19
          ClassOfMethodDecl = IMPD->getClassInterface();
1433
4
        else if (ObjCCategoryImplDecl* CatImplClass =
1434
4
                   dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
1435
4
          ClassOfMethodDecl = CatImplClass->getClassInterface();
1436
23
      }
1437
511
      if (!S.getLangOpts().DebuggerSupport) {
1438
501
        if (IV->getAccessControl() == ObjCIvarDecl::Private) {
1439
63
          if (!declaresSameEntity(ClassDeclared, IDecl) ||
1440
63
              
!declaresSameEntity(ClassOfMethodDecl, ClassDeclared)60
)
1441
10
            S.Diag(MemberLoc, diag::err_private_ivar_access)
1442
10
              << IV->getDeclName();
1443
438
        } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
1444
          // @protected
1445
14
          S.Diag(MemberLoc, diag::err_protected_ivar_access)
1446
14
              << IV->getDeclName();
1447
501
      }
1448
511
    }
1449
1.04k
    bool warn = true;
1450
1.04k
    if (S.getLangOpts().ObjCWeak) {
1451
68
      Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
1452
68
      if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
1453
4
        if (UO->getOpcode() == UO_Deref)
1454
4
          BaseExp = UO->getSubExpr()->IgnoreParenCasts();
1455
1456
68
      if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
1457
60
        if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1458
9
          S.Diag(DE->getLocation(), diag::err_arc_weak_ivar_access);
1459
9
          warn = false;
1460
9
        }
1461
68
    }
1462
1.04k
    if (warn) {
1463
1.04k
      if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
1464
560
        ObjCMethodFamily MF = MD->getMethodFamily();
1465
560
        warn = (MF != OMF_init && 
MF != OMF_dealloc386
&&
1466
560
                
MF != OMF_finalize383
&&
1467
560
                
!S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV)383
);
1468
560
      }
1469
1.04k
      if (warn)
1470
863
        S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
1471
1.04k
    }
1472
1473
1.04k
    ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
1474
1.04k
        IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
1475
1.04k
        IsArrow);
1476
1477
1.04k
    if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
1478
22
      if (!S.isUnevaluatedContext() &&
1479
22
          !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
1480
20
        S.getCurFunction()->recordUseOfWeak(Result);
1481
22
    }
1482
1483
1.04k
    return Result;
1484
1.04k
  }
1485
1486
  // Objective-C property access.
1487
2.86k
  const ObjCObjectPointerType *OPT;
1488
2.86k
  if (!IsArrow && 
(OPT = BaseType->getAs<ObjCObjectPointerType>())2.85k
) {
1489
2.20k
    if (!SS.isEmpty() && 
!SS.isInvalid()2
) {
1490
1
      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
1491
1
          << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
1492
1
      SS.clear();
1493
1
    }
1494
1495
    // This actually uses the base as an r-value.
1496
2.20k
    BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
1497
2.20k
    if (BaseExpr.isInvalid())
1498
0
      return ExprError();
1499
1500
2.20k
    assert(S.Context.hasSameUnqualifiedType(BaseType,
1501
2.20k
                                            BaseExpr.get()->getType()));
1502
1503
0
    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1504
1505
2.20k
    const ObjCObjectType *OT = OPT->getObjectType();
1506
1507
    // id, with and without qualifiers.
1508
2.20k
    if (OT->isObjCId()) {
1509
      // Check protocols on qualified interfaces.
1510
34
      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
1511
34
      if (Decl *PMDecl =
1512
34
              FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
1513
24
        if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
1514
          // Check the use of this declaration
1515
13
          if (S.DiagnoseUseOfDecl(PD, MemberLoc))
1516
0
            return ExprError();
1517
1518
13
          return new (S.Context)
1519
13
              ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
1520
13
                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
1521
13
        }
1522
1523
11
        if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
1524
11
          Selector SetterSel =
1525
11
            SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1526
11
                                                   S.PP.getSelectorTable(),
1527
11
                                                   Member);
1528
11
          ObjCMethodDecl *SMD = nullptr;
1529
11
          if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
1530
11
                                                     /*Property id*/ nullptr,
1531
11
                                                     SetterSel, S.Context))
1532
7
            SMD = dyn_cast<ObjCMethodDecl>(SDecl);
1533
1534
11
          return new (S.Context)
1535
11
              ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
1536
11
                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
1537
11
        }
1538
11
      }
1539
      // Use of id.member can only be for a property reference. Do not
1540
      // use the 'id' redefinition in this case.
1541
10
      if (IsArrow && 
ShouldTryAgainWithRedefinitionType(S, BaseExpr)0
)
1542
0
        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1543
0
                                ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1544
1545
10
      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1546
10
                         << MemberName << BaseType);
1547
10
    }
1548
1549
    // 'Class', unqualified only.
1550
2.16k
    if (OT->isObjCClass()) {
1551
      // Only works in a method declaration (??!).
1552
9
      ObjCMethodDecl *MD = S.getCurMethodDecl();
1553
9
      if (!MD) {
1554
0
        if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1555
0
          return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1556
0
                                  ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1557
1558
0
        goto fail;
1559
0
      }
1560
1561
      // Also must look for a getter name which uses property syntax.
1562
9
      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
1563
9
      ObjCInterfaceDecl *IFace = MD->getClassInterface();
1564
9
      if (!IFace)
1565
1
        goto fail;
1566
1567
8
      ObjCMethodDecl *Getter;
1568
8
      if ((Getter = IFace->lookupClassMethod(Sel))) {
1569
        // Check the use of this method.
1570
6
        if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
1571
0
          return ExprError();
1572
6
      } else
1573
2
        Getter = IFace->lookupPrivateMethod(Sel, false);
1574
      // If we found a getter then this may be a valid dot-reference, we
1575
      // will look for the matching setter, in case it is needed.
1576
8
      Selector SetterSel =
1577
8
        SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
1578
8
                                               S.PP.getSelectorTable(),
1579
8
                                               Member);
1580
8
      ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
1581
8
      if (!Setter) {
1582
        // If this reference is in an @implementation, also check for 'private'
1583
        // methods.
1584
3
        Setter = IFace->lookupPrivateMethod(SetterSel, false);
1585
3
      }
1586
1587
8
      if (Setter && 
S.DiagnoseUseOfDecl(Setter, MemberLoc)6
)
1588
0
        return ExprError();
1589
1590
8
      if (Getter || 
Setter0
) {
1591
8
        return new (S.Context) ObjCPropertyRefExpr(
1592
8
            Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
1593
8
            OK_ObjCProperty, MemberLoc, BaseExpr.get());
1594
8
      }
1595
1596
0
      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
1597
0
        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1598
0
                                ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1599
1600
0
      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
1601
0
                         << MemberName << BaseType);
1602
0
    }
1603
1604
    // Normal property access.
1605
2.16k
    return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
1606
2.16k
                                       MemberLoc, SourceLocation(), QualType(),
1607
2.16k
                                       false);
1608
2.16k
  }
1609
1610
661
  if (BaseType->isExtVectorBoolType()) {
1611
    // We disallow element access for ext_vector_type bool.  There is no way to
1612
    // materialize a reference to a vector element as a pointer (each element is
1613
    // one bit in the vector).
1614
4
    S.Diag(R.getNameLoc(), diag::err_ext_vector_component_name_illegal)
1615
4
        << MemberName
1616
4
        << (BaseExpr.get() ? BaseExpr.get()->getSourceRange() : 
SourceRange()0
);
1617
4
    return ExprError();
1618
4
  }
1619
1620
  // Handle 'field access' to vectors, such as 'V.xx'.
1621
657
  if (BaseType->isExtVectorType()) {
1622
    // FIXME: this expr should store IsArrow.
1623
523
    IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
1624
523
    ExprValueKind VK;
1625
523
    if (IsArrow)
1626
5
      VK = VK_LValue;
1627
518
    else {
1628
518
      if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(BaseExpr.get()))
1629
2
        VK = POE->getSyntacticForm()->getValueKind();
1630
516
      else
1631
516
        VK = BaseExpr.get()->getValueKind();
1632
518
    }
1633
1634
523
    QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
1635
523
                                           Member, MemberLoc);
1636
523
    if (ret.isNull())
1637
27
      return ExprError();
1638
496
    Qualifiers BaseQ =
1639
496
        S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers();
1640
496
    ret = S.Context.getQualifiedType(ret, BaseQ);
1641
1642
496
    return new (S.Context)
1643
496
        ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
1644
523
  }
1645
1646
  // Adjust builtin-sel to the appropriate redefinition type if that's
1647
  // not just a pointer to builtin-sel again.
1648
134
  if (IsArrow && 
BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel)7
&&
1649
134
      
!S.Context.getObjCSelRedefinitionType()->isObjCSelType()2
) {
1650
2
    BaseExpr = S.ImpCastExprToType(
1651
2
        BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
1652
2
    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1653
2
                            ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1654
2
  }
1655
1656
  // Failure cases.
1657
147
 fail:
1658
1659
  // Recover from dot accesses to pointers, e.g.:
1660
  //   type *foo;
1661
  //   foo.bar
1662
  // This is actually well-formed in two cases:
1663
  //   - 'type' is an Objective C type
1664
  //   - 'bar' is a pseudo-destructor name which happens to refer to
1665
  //     the appropriate pointer type
1666
147
  if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
1667
46
    if (!IsArrow && 
Ptr->getPointeeType()->isRecordType()45
&&
1668
46
        
MemberName.getNameKind() != DeclarationName::CXXDestructorName42
) {
1669
42
      S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
1670
42
          << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
1671
42
          << FixItHint::CreateReplacement(OpLoc, "->");
1672
1673
42
      if (S.isSFINAEContext())
1674
11
        return ExprError();
1675
1676
      // Recurse as an -> access.
1677
31
      IsArrow = true;
1678
31
      return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1679
31
                              ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1680
42
    }
1681
46
  }
1682
1683
  // If the user is trying to apply -> or . to a function name, it's probably
1684
  // because they forgot parentheses to call that function.
1685
105
  if (S.tryToRecoverWithCall(
1686
105
          BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
1687
105
          /*complain*/ false,
1688
105
          IsArrow ? 
&isPointerToRecordType19
:
&isRecordType86
)) {
1689
11
    if (BaseExpr.isInvalid())
1690
0
      return ExprError();
1691
11
    BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
1692
11
    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
1693
11
                            ObjCImpDecl, HasTemplateArgs, TemplateKWLoc);
1694
11
  }
1695
1696
94
  S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
1697
94
    << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
1698
1699
94
  return ExprError();
1700
105
}
1701
1702
/// The main callback when the parser finds something like
1703
///   expression . [nested-name-specifier] identifier
1704
///   expression -> [nested-name-specifier] identifier
1705
/// where 'identifier' encompasses a fairly broad spectrum of
1706
/// possibilities, including destructor and operator references.
1707
///
1708
/// \param OpKind either tok::arrow or tok::period
1709
/// \param ObjCImpDecl the current Objective-C \@implementation
1710
///   decl; this is an ugly hack around the fact that Objective-C
1711
///   \@implementations aren't properly put in the context chain
1712
ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
1713
                                       SourceLocation OpLoc,
1714
                                       tok::TokenKind OpKind,
1715
                                       CXXScopeSpec &SS,
1716
                                       SourceLocation TemplateKWLoc,
1717
                                       UnqualifiedId &Id,
1718
1.17M
                                       Decl *ObjCImpDecl) {
1719
1.17M
  if (SS.isSet() && 
SS.isInvalid()653
)
1720
0
    return ExprError();
1721
1722
  // Warn about the explicit constructor calls Microsoft extension.
1723
1.17M
  if (getLangOpts().MicrosoftExt &&
1724
1.17M
      
Id.getKind() == UnqualifiedIdKind::IK_ConstructorName3.94k
)
1725
14
    Diag(Id.getSourceRange().getBegin(),
1726
14
         diag::ext_ms_explicit_constructor_call);
1727
1728
1.17M
  TemplateArgumentListInfo TemplateArgsBuffer;
1729
1730
  // Decompose the name into its component parts.
1731
1.17M
  DeclarationNameInfo NameInfo;
1732
1.17M
  const TemplateArgumentListInfo *TemplateArgs;
1733
1.17M
  DecomposeUnqualifiedId(Id, TemplateArgsBuffer,
1734
1.17M
                         NameInfo, TemplateArgs);
1735
1736
1.17M
  DeclarationName Name = NameInfo.getName();
1737
1.17M
  bool IsArrow = (OpKind == tok::arrow);
1738
1739
1.17M
  if (getLangOpts().HLSL && 
IsArrow24
)
1740
2
    return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 2);
1741
1742
1.17M
  NamedDecl *FirstQualifierInScope
1743
1.17M
    = (!SS.isSet() ? 
nullptr1.17M
:
FindFirstQualifierInScope(S, SS.getScopeRep())653
);
1744
1745
  // This is a postfix expression, so get rid of ParenListExprs.
1746
1.17M
  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
1747
1.17M
  if (Result.isInvalid()) 
return ExprError()0
;
1748
1.17M
  Base = Result.get();
1749
1750
1.17M
  if (Base->getType()->isDependentType() || 
Name.isDependentName()402k
||
1751
1.17M
      
isDependentScopeSpecifier(SS)402k
) {
1752
774k
    return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
1753
774k
                                    TemplateKWLoc, FirstQualifierInScope,
1754
774k
                                    NameInfo, TemplateArgs);
1755
774k
  }
1756
1757
402k
  ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl};
1758
402k
  ExprResult Res = BuildMemberReferenceExpr(
1759
402k
      Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc,
1760
402k
      FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs);
1761
1762
402k
  if (!Res.isInvalid() && 
isa<MemberExpr>(Res.get())401k
)
1763
373k
    CheckMemberAccessOfNoDeref(cast<MemberExpr>(Res.get()));
1764
1765
402k
  return Res;
1766
1.17M
}
1767
1768
373k
void Sema::CheckMemberAccessOfNoDeref(const MemberExpr *E) {
1769
373k
  if (isUnevaluatedContext())
1770
858
    return;
1771
1772
372k
  QualType ResultTy = E->getType();
1773
1774
  // Member accesses have four cases:
1775
  // 1: non-array member via "->": dereferences
1776
  // 2: non-array member via ".": nothing interesting happens
1777
  // 3: array member access via "->": nothing interesting happens
1778
  //    (this returns an array lvalue and does not actually dereference memory)
1779
  // 4: array member access via ".": *adds* a layer of indirection
1780
372k
  if (ResultTy->isArrayType()) {
1781
48.9k
    if (!E->isArrow()) {
1782
      // This might be something like:
1783
      //     (*structPtr).arrayMember
1784
      // which behaves roughly like:
1785
      //     &(*structPtr).pointerMember
1786
      // in that the apparent dereference in the base expression does not
1787
      // actually happen.
1788
43.6k
      CheckAddressOfNoDeref(E->getBase());
1789
43.6k
    }
1790
323k
  } else if (E->isArrow()) {
1791
131k
    if (const auto *Ptr = dyn_cast<PointerType>(
1792
131k
            E->getBase()->getType().getDesugaredType(Context))) {
1793
131k
      if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
1794
19
        ExprEvalContexts.back().PossibleDerefs.insert(E);
1795
131k
    }
1796
131k
  }
1797
372k
}
1798
1799
ExprResult
1800
Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
1801
                              SourceLocation OpLoc, const CXXScopeSpec &SS,
1802
                              FieldDecl *Field, DeclAccessPair FoundDecl,
1803
832k
                              const DeclarationNameInfo &MemberNameInfo) {
1804
  // x.a is an l-value if 'a' has a reference type. Otherwise:
1805
  // x.a is an l-value/x-value/pr-value if the base is (and note
1806
  //   that *x is always an l-value), except that if the base isn't
1807
  //   an ordinary object then we must have an rvalue.
1808
832k
  ExprValueKind VK = VK_LValue;
1809
832k
  ExprObjectKind OK = OK_Ordinary;
1810
832k
  if (!IsArrow) {
1811
272k
    if (BaseExpr->getObjectKind() == OK_Ordinary)
1812
272k
      VK = BaseExpr->getValueKind();
1813
0
    else
1814
0
      VK = VK_PRValue;
1815
272k
  }
1816
832k
  if (VK != VK_PRValue && 
Field->isBitField()832k
)
1817
11.9k
    OK = OK_BitField;
1818
1819
  // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref]
1820
832k
  QualType MemberType = Field->getType();
1821
832k
  if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) {
1822
8.48k
    MemberType = Ref->getPointeeType();
1823
8.48k
    VK = VK_LValue;
1824
823k
  } else {
1825
823k
    QualType BaseType = BaseExpr->getType();
1826
823k
    if (IsArrow) 
BaseType = BaseType->castAs<PointerType>()->getPointeeType()552k
;
1827
1828
823k
    Qualifiers BaseQuals = BaseType.getQualifiers();
1829
1830
    // GC attributes are never picked up by members.
1831
823k
    BaseQuals.removeObjCGCAttr();
1832
1833
    // CVR attributes from the base are picked up by members,
1834
    // except that 'mutable' members don't pick up 'const'.
1835
823k
    if (Field->isMutable()) 
BaseQuals.removeConst()17.1k
;
1836
1837
823k
    Qualifiers MemberQuals =
1838
823k
        Context.getCanonicalType(MemberType).getQualifiers();
1839
1840
823k
    assert(!MemberQuals.hasAddressSpace());
1841
1842
0
    Qualifiers Combined = BaseQuals + MemberQuals;
1843
823k
    if (Combined != MemberQuals)
1844
222k
      MemberType = Context.getQualifiedType(MemberType, Combined);
1845
1846
    // Pick up NoDeref from the base in case we end up using AddrOf on the
1847
    // result. E.g. the expression
1848
    //     &someNoDerefPtr->pointerMember
1849
    // should be a noderef pointer again.
1850
823k
    if (BaseType->hasAttr(attr::NoDeref))
1851
35
      MemberType =
1852
35
          Context.getAttributedType(attr::NoDeref, MemberType, MemberType);
1853
823k
  }
1854
1855
0
  auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
1856
832k
  if (!(CurMethod && 
CurMethod->isDefaulted()512k
))
1857
786k
    UnusedPrivateFields.remove(Field);
1858
1859
832k
  ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(),
1860
832k
                                                  FoundDecl, Field);
1861
832k
  if (Base.isInvalid())
1862
12
    return ExprError();
1863
1864
  // Build a reference to a private copy for non-static data members in
1865
  // non-static member functions, privatized by OpenMP constructs.
1866
832k
  if (getLangOpts().OpenMP && 
IsArrow41.5k
&&
1867
832k
      
!CurContext->isDependentContext()22.6k
&&
1868
832k
      
isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())17.3k
) {
1869
15.6k
    if (auto *PrivateCopy = isOpenMPCapturedDecl(Field)) {
1870
2.18k
      return getOpenMPCapturedExpr(PrivateCopy, VK, OK,
1871
2.18k
                                   MemberNameInfo.getLoc());
1872
2.18k
    }
1873
15.6k
  }
1874
1875
830k
  return BuildMemberExpr(Base.get(), IsArrow, OpLoc, &SS,
1876
830k
                         /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
1877
830k
                         /*HadMultipleCandidates=*/false, MemberNameInfo,
1878
830k
                         MemberType, VK, OK);
1879
832k
}
1880
1881
/// Builds an implicit member access expression.  The current context
1882
/// is known to be an instance method, and the given unqualified lookup
1883
/// set is known to contain only instance members, at least one of which
1884
/// is from an appropriate type.
1885
ExprResult
1886
Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
1887
                              SourceLocation TemplateKWLoc,
1888
                              LookupResult &R,
1889
                              const TemplateArgumentListInfo *TemplateArgs,
1890
724k
                              bool IsKnownInstance, const Scope *S) {
1891
724k
  assert(!R.empty() && !R.isAmbiguous());
1892
1893
0
  SourceLocation loc = R.getNameLoc();
1894
1895
  // If this is known to be an instance access, go ahead and build an
1896
  // implicit 'this' expression now.
1897
724k
  QualType ThisTy = getCurrentThisType();
1898
724k
  assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
1899
1900
0
  Expr *baseExpr = nullptr; // null signifies implicit access
1901
724k
  if (IsKnownInstance) {
1902
722k
    SourceLocation Loc = R.getNameLoc();
1903
722k
    if (SS.getRange().isValid())
1904
4.35k
      Loc = SS.getRange().getBegin();
1905
722k
    baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
1906
722k
  }
1907
1908
724k
  return BuildMemberReferenceExpr(baseExpr, ThisTy,
1909
724k
                                  /*OpLoc*/ SourceLocation(),
1910
724k
                                  /*IsArrow*/ true,
1911
724k
                                  SS, TemplateKWLoc,
1912
724k
                                  /*FirstQualifierInScope*/ nullptr,
1913
724k
                                  R, TemplateArgs, S);
1914
724k
}