Coverage Report

Created: 2019-07-24 05:18

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