Coverage Report

Created: 2021-08-24 07:12

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