Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===//
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 for expressions involving
10
//  pseudo-object references.  Pseudo-objects are conceptual objects
11
//  whose storage is entirely abstract and all accesses to which are
12
//  translated through some sort of abstraction barrier.
13
//
14
//  For example, Objective-C objects can have "properties", either
15
//  declared or undeclared.  A property may be accessed by writing
16
//    expr.prop
17
//  where 'expr' is an r-value of Objective-C pointer type and 'prop'
18
//  is the name of the property.  If this expression is used in a context
19
//  needing an r-value, it is treated as if it were a message-send
20
//  of the associated 'getter' selector, typically:
21
//    [expr prop]
22
//  If it is used as the LHS of a simple assignment, it is treated
23
//  as a message-send of the associated 'setter' selector, typically:
24
//    [expr setProp: RHS]
25
//  If it is used as the LHS of a compound assignment, or the operand
26
//  of a unary increment or decrement, both are required;  for example,
27
//  'expr.prop *= 100' would be translated to:
28
//    [expr setProp: [expr prop] * 100]
29
//
30
//===----------------------------------------------------------------------===//
31
32
#include "clang/Sema/SemaInternal.h"
33
#include "clang/AST/ExprCXX.h"
34
#include "clang/AST/ExprObjC.h"
35
#include "clang/Basic/CharInfo.h"
36
#include "clang/Lex/Preprocessor.h"
37
#include "clang/Sema/Initialization.h"
38
#include "clang/Sema/ScopeInfo.h"
39
#include "llvm/ADT/SmallString.h"
40
41
using namespace clang;
42
using namespace sema;
43
44
namespace {
45
  // Basically just a very focused copy of TreeTransform.
46
  struct Rebuilder {
47
    Sema &S;
48
    unsigned MSPropertySubscriptCount;
49
    typedef llvm::function_ref<Expr *(Expr *, unsigned)> SpecificRebuilderRefTy;
50
    const SpecificRebuilderRefTy &SpecificCallback;
51
    Rebuilder(Sema &S, const SpecificRebuilderRefTy &SpecificCallback)
52
        : S(S), MSPropertySubscriptCount(0),
53
2.43k
          SpecificCallback(SpecificCallback) {}
54
55
1.90k
    Expr *rebuildObjCPropertyRefExpr(ObjCPropertyRefExpr *refExpr) {
56
1.90k
      // Fortunately, the constraint that we're rebuilding something
57
1.90k
      // with a base limits the number of cases here.
58
1.90k
      if (refExpr->isClassReceiver() || 
refExpr->isSuperReceiver()1.90k
)
59
1
        return refExpr;
60
1.90k
61
1.90k
      if (refExpr->isExplicitProperty()) {
62
1.62k
        return new (S.Context) ObjCPropertyRefExpr(
63
1.62k
            refExpr->getExplicitProperty(), refExpr->getType(),
64
1.62k
            refExpr->getValueKind(), refExpr->getObjectKind(),
65
1.62k
            refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0));
66
1.62k
      }
67
283
      return new (S.Context) ObjCPropertyRefExpr(
68
283
          refExpr->getImplicitPropertyGetter(),
69
283
          refExpr->getImplicitPropertySetter(), refExpr->getType(),
70
283
          refExpr->getValueKind(), refExpr->getObjectKind(),
71
283
          refExpr->getLocation(), SpecificCallback(refExpr->getBase(), 0));
72
283
    }
73
252
    Expr *rebuildObjCSubscriptRefExpr(ObjCSubscriptRefExpr *refExpr) {
74
252
      assert(refExpr->getBaseExpr());
75
252
      assert(refExpr->getKeyExpr());
76
252
77
252
      return new (S.Context) ObjCSubscriptRefExpr(
78
252
          SpecificCallback(refExpr->getBaseExpr(), 0),
79
252
          SpecificCallback(refExpr->getKeyExpr(), 1), refExpr->getType(),
80
252
          refExpr->getValueKind(), refExpr->getObjectKind(),
81
252
          refExpr->getAtIndexMethodDecl(), refExpr->setAtIndexMethodDecl(),
82
252
          refExpr->getRBracket());
83
252
    }
84
278
    Expr *rebuildMSPropertyRefExpr(MSPropertyRefExpr *refExpr) {
85
278
      assert(refExpr->getBaseExpr());
86
278
87
278
      return new (S.Context) MSPropertyRefExpr(
88
278
          SpecificCallback(refExpr->getBaseExpr(), 0),
89
278
          refExpr->getPropertyDecl(), refExpr->isArrow(), refExpr->getType(),
90
278
          refExpr->getValueKind(), refExpr->getQualifierLoc(),
91
278
          refExpr->getMemberLoc());
92
278
    }
93
166
    Expr *rebuildMSPropertySubscriptExpr(MSPropertySubscriptExpr *refExpr) {
94
166
      assert(refExpr->getBase());
95
166
      assert(refExpr->getIdx());
96
166
97
166
      auto *NewBase = rebuild(refExpr->getBase());
98
166
      ++MSPropertySubscriptCount;
99
166
      return new (S.Context) MSPropertySubscriptExpr(
100
166
          NewBase,
101
166
          SpecificCallback(refExpr->getIdx(), MSPropertySubscriptCount),
102
166
          refExpr->getType(), refExpr->getValueKind(), refExpr->getObjectKind(),
103
166
          refExpr->getRBracketLoc());
104
166
    }
105
106
2.67k
    Expr *rebuild(Expr *e) {
107
2.67k
      // Fast path: nothing to look through.
108
2.67k
      if (auto *PRE = dyn_cast<ObjCPropertyRefExpr>(e))
109
1.90k
        return rebuildObjCPropertyRefExpr(PRE);
110
763
      if (auto *SRE = dyn_cast<ObjCSubscriptRefExpr>(e))
111
252
        return rebuildObjCSubscriptRefExpr(SRE);
112
511
      if (auto *MSPRE = dyn_cast<MSPropertyRefExpr>(e))
113
278
        return rebuildMSPropertyRefExpr(MSPRE);
114
233
      if (auto *MSPSE = dyn_cast<MSPropertySubscriptExpr>(e))
115
166
        return rebuildMSPropertySubscriptExpr(MSPSE);
116
67
117
67
      // Otherwise, we should look through and rebuild anything that
118
67
      // IgnoreParens would.
119
67
120
67
      if (ParenExpr *parens = dyn_cast<ParenExpr>(e)) {
121
66
        e = rebuild(parens->getSubExpr());
122
66
        return new (S.Context) ParenExpr(parens->getLParen(),
123
66
                                         parens->getRParen(),
124
66
                                         e);
125
66
      }
126
1
127
1
      if (UnaryOperator *uop = dyn_cast<UnaryOperator>(e)) {
128
0
        assert(uop->getOpcode() == UO_Extension);
129
0
        e = rebuild(uop->getSubExpr());
130
0
        return new (S.Context) UnaryOperator(e, uop->getOpcode(),
131
0
                                             uop->getType(),
132
0
                                             uop->getValueKind(),
133
0
                                             uop->getObjectKind(),
134
0
                                             uop->getOperatorLoc(),
135
0
                                             uop->canOverflow());
136
0
      }
137
1
138
1
      if (GenericSelectionExpr *gse = dyn_cast<GenericSelectionExpr>(e)) {
139
0
        assert(!gse->isResultDependent());
140
0
        unsigned resultIndex = gse->getResultIndex();
141
0
        unsigned numAssocs = gse->getNumAssocs();
142
0
143
0
        SmallVector<Expr *, 8> assocExprs;
144
0
        SmallVector<TypeSourceInfo *, 8> assocTypes;
145
0
        assocExprs.reserve(numAssocs);
146
0
        assocTypes.reserve(numAssocs);
147
0
148
0
        for (const GenericSelectionExpr::Association &assoc :
149
0
             gse->associations()) {
150
0
          Expr *assocExpr = assoc.getAssociationExpr();
151
0
          if (assoc.isSelected())
152
0
            assocExpr = rebuild(assocExpr);
153
0
          assocExprs.push_back(assocExpr);
154
0
          assocTypes.push_back(assoc.getTypeSourceInfo());
155
0
        }
156
0
157
0
        return GenericSelectionExpr::Create(
158
0
            S.Context, gse->getGenericLoc(), gse->getControllingExpr(),
159
0
            assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
160
0
            gse->containsUnexpandedParameterPack(), resultIndex);
161
0
      }
162
1
163
1
      if (ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
164
1
        assert(!ce->isConditionDependent());
165
1
166
1
        Expr *LHS = ce->getLHS(), *RHS = ce->getRHS();
167
1
        Expr *&rebuiltExpr = ce->isConditionTrue() ? 
LHS0
: RHS;
168
1
        rebuiltExpr = rebuild(rebuiltExpr);
169
1
170
1
        return new (S.Context) ChooseExpr(ce->getBuiltinLoc(),
171
1
                                          ce->getCond(),
172
1
                                          LHS, RHS,
173
1
                                          rebuiltExpr->getType(),
174
1
                                          rebuiltExpr->getValueKind(),
175
1
                                          rebuiltExpr->getObjectKind(),
176
1
                                          ce->getRParenLoc(),
177
1
                                          ce->isConditionTrue(),
178
1
                                          rebuiltExpr->isTypeDependent(),
179
1
                                          rebuiltExpr->isValueDependent());
180
1
      }
181
0
182
0
      llvm_unreachable("bad expression to rebuild!");
183
0
    }
184
  };
185
186
  class PseudoOpBuilder {
187
  public:
188
    Sema &S;
189
    unsigned ResultIndex;
190
    SourceLocation GenericLoc;
191
    bool IsUnique;
192
    SmallVector<Expr *, 4> Semantics;
193
194
    PseudoOpBuilder(Sema &S, SourceLocation genericLoc, bool IsUnique)
195
      : S(S), ResultIndex(PseudoObjectExpr::NoResult),
196
2.68k
        GenericLoc(genericLoc), IsUnique(IsUnique) {}
197
198
2.68k
    virtual ~PseudoOpBuilder() {}
199
200
    /// Add a normal semantic expression.
201
5.05k
    void addSemanticExpr(Expr *semantic) {
202
5.05k
      Semantics.push_back(semantic);
203
5.05k
    }
204
205
    /// Add the 'result' semantic expression.
206
1.67k
    void addResultSemanticExpr(Expr *resultExpr) {
207
1.67k
      assert(ResultIndex == PseudoObjectExpr::NoResult);
208
1.67k
      ResultIndex = Semantics.size();
209
1.67k
      Semantics.push_back(resultExpr);
210
1.67k
      // An OVE is not unique if it is used as the result expression.
211
1.67k
      if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
212
0
        OVE->setIsUnique(false);
213
1.67k
    }
214
215
    ExprResult buildRValueOperation(Expr *op);
216
    ExprResult buildAssignmentOperation(Scope *Sc,
217
                                        SourceLocation opLoc,
218
                                        BinaryOperatorKind opcode,
219
                                        Expr *LHS, Expr *RHS);
220
    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
221
                                    UnaryOperatorKind opcode,
222
                                    Expr *op);
223
224
    virtual ExprResult complete(Expr *syntacticForm);
225
226
    OpaqueValueExpr *capture(Expr *op);
227
    OpaqueValueExpr *captureValueAsResult(Expr *op);
228
229
498
    void setResultToLastSemantic() {
230
498
      assert(ResultIndex == PseudoObjectExpr::NoResult);
231
498
      ResultIndex = Semantics.size() - 1;
232
498
      // An OVE is not unique if it is used as the result expression.
233
498
      if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
234
466
        OVE->setIsUnique(false);
235
498
    }
236
237
    /// Return true if assignments have a non-void result.
238
850
    static bool CanCaptureValue(Expr *exp) {
239
850
      if (exp->isGLValue())
240
5
        return true;
241
845
      QualType ty = exp->getType();
242
845
      assert(!ty->isIncompleteType());
243
845
      assert(!ty->isDependentType());
244
845
245
845
      if (const CXXRecordDecl *ClassDecl = ty->getAsCXXRecordDecl())
246
19
        return ClassDecl->isTriviallyCopyable();
247
826
      return true;
248
826
    }
249
250
    virtual Expr *rebuildAndCaptureObject(Expr *) = 0;
251
    virtual ExprResult buildGet() = 0;
252
    virtual ExprResult buildSet(Expr *, SourceLocation,
253
                                bool captureSetValueAsResult) = 0;
254
    /// Should the result of an assignment be the formal result of the
255
    /// setter call or the value that was passed to the setter?
256
    ///
257
    /// Different pseudo-object language features use different language rules
258
    /// for this.
259
    /// The default is to use the set value.  Currently, this affects the
260
    /// behavior of simple assignments, compound assignments, and prefix
261
    /// increment and decrement.
262
    /// Postfix increment and decrement always use the getter result as the
263
    /// expression result.
264
    ///
265
    /// If this method returns true, and the set value isn't capturable for
266
    /// some reason, the result of the expression will be void.
267
1.65k
    virtual bool captureSetValueAsResult() const { return true; }
268
  };
269
270
  /// A PseudoOpBuilder for Objective-C \@properties.
271
  class ObjCPropertyOpBuilder : public PseudoOpBuilder {
272
    ObjCPropertyRefExpr *RefExpr;
273
    ObjCPropertyRefExpr *SyntacticRefExpr;
274
    OpaqueValueExpr *InstanceReceiver;
275
    ObjCMethodDecl *Getter;
276
277
    ObjCMethodDecl *Setter;
278
    Selector SetterSelector;
279
    Selector GetterSelector;
280
281
  public:
282
    ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr, bool IsUnique)
283
        : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
284
          RefExpr(refExpr), SyntacticRefExpr(nullptr),
285
2.16k
          InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
286
2.16k
    }
287
288
    ExprResult buildRValueOperation(Expr *op);
289
    ExprResult buildAssignmentOperation(Scope *Sc,
290
                                        SourceLocation opLoc,
291
                                        BinaryOperatorKind opcode,
292
                                        Expr *LHS, Expr *RHS);
293
    ExprResult buildIncDecOperation(Scope *Sc, SourceLocation opLoc,
294
                                    UnaryOperatorKind opcode,
295
                                    Expr *op);
296
297
    bool tryBuildGetOfReference(Expr *op, ExprResult &result);
298
    bool findSetter(bool warn=true);
299
    bool findGetter();
300
    void DiagnoseUnsupportedPropertyUse();
301
302
    Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
303
    ExprResult buildGet() override;
304
    ExprResult buildSet(Expr *op, SourceLocation, bool) override;
305
    ExprResult complete(Expr *SyntacticForm) override;
306
307
    bool isWeakProperty() const;
308
  };
309
310
 /// A PseudoOpBuilder for Objective-C array/dictionary indexing.
311
 class ObjCSubscriptOpBuilder : public PseudoOpBuilder {
312
   ObjCSubscriptRefExpr *RefExpr;
313
   OpaqueValueExpr *InstanceBase;
314
   OpaqueValueExpr *InstanceKey;
315
   ObjCMethodDecl *AtIndexGetter;
316
   Selector AtIndexGetterSelector;
317
318
   ObjCMethodDecl *AtIndexSetter;
319
   Selector AtIndexSetterSelector;
320
321
 public:
322
   ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr, bool IsUnique)
323
       : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
324
         RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
325
262
         AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
326
327
   ExprResult buildRValueOperation(Expr *op);
328
   ExprResult buildAssignmentOperation(Scope *Sc,
329
                                       SourceLocation opLoc,
330
                                       BinaryOperatorKind opcode,
331
                                       Expr *LHS, Expr *RHS);
332
   Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
333
334
   bool findAtIndexGetter();
335
   bool findAtIndexSetter();
336
337
   ExprResult buildGet() override;
338
   ExprResult buildSet(Expr *op, SourceLocation, bool) override;
339
 };
340
341
 class MSPropertyOpBuilder : public PseudoOpBuilder {
342
   MSPropertyRefExpr *RefExpr;
343
   OpaqueValueExpr *InstanceBase;
344
   SmallVector<Expr *, 4> CallArgs;
345
346
   MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E);
347
348
 public:
349
   MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr, bool IsUnique)
350
       : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
351
178
         RefExpr(refExpr), InstanceBase(nullptr) {}
352
   MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr, bool IsUnique)
353
       : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
354
72
         InstanceBase(nullptr) {
355
72
     RefExpr = getBaseMSProperty(refExpr);
356
72
   }
357
358
   Expr *rebuildAndCaptureObject(Expr *) override;
359
   ExprResult buildGet() override;
360
   ExprResult buildSet(Expr *op, SourceLocation, bool) override;
361
158
   bool captureSetValueAsResult() const override { return false; }
362
 };
363
}
364
365
/// Capture the given expression in an OpaqueValueExpr.
366
4.15k
OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
367
4.15k
  // Make a new OVE whose source is the given expression.
368
4.15k
  OpaqueValueExpr *captured =
369
4.15k
    new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
370
4.15k
                                    e->getValueKind(), e->getObjectKind(),
371
4.15k
                                    e);
372
4.15k
  if (IsUnique)
373
3.97k
    captured->setIsUnique(true);
374
4.15k
375
4.15k
  // Make sure we bind that in the semantics.
376
4.15k
  addSemanticExpr(captured);
377
4.15k
  return captured;
378
4.15k
}
379
380
/// Capture the given expression as the result of this pseudo-object
381
/// operation.  This routine is safe against expressions which may
382
/// already be captured.
383
///
384
/// \returns the captured expression, which will be the
385
///   same as the input if the input was already captured
386
807
OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
387
807
  assert(ResultIndex == PseudoObjectExpr::NoResult);
388
807
389
807
  // If the expression hasn't already been captured, just capture it
390
807
  // and set the new semantic
391
807
  if (!isa<OpaqueValueExpr>(e)) {
392
455
    OpaqueValueExpr *cap = capture(e);
393
455
    setResultToLastSemantic();
394
455
    return cap;
395
455
  }
396
352
397
352
  // Otherwise, it must already be one of our semantic expressions;
398
352
  // set ResultIndex to its index.
399
352
  unsigned index = 0;
400
686
  for (;; 
++index334
) {
401
686
    assert(index < Semantics.size() &&
402
686
           "captured expression not found in semantics!");
403
686
    if (e == Semantics[index]) 
break352
;
404
686
  }
405
352
  ResultIndex = index;
406
352
  // An OVE is not unique if it is used as the result expression.
407
352
  cast<OpaqueValueExpr>(e)->setIsUnique(false);
408
352
  return cast<OpaqueValueExpr>(e);
409
352
}
410
411
/// The routine which creates the final PseudoObjectExpr.
412
2.56k
ExprResult PseudoOpBuilder::complete(Expr *syntactic) {
413
2.56k
  return PseudoObjectExpr::Create(S.Context, syntactic,
414
2.56k
                                  Semantics, ResultIndex);
415
2.56k
}
416
417
/// The main skeleton for building an r-value operation.
418
1.70k
ExprResult PseudoOpBuilder::buildRValueOperation(Expr *op) {
419
1.70k
  Expr *syntacticBase = rebuildAndCaptureObject(op);
420
1.70k
421
1.70k
  ExprResult getExpr = buildGet();
422
1.70k
  if (getExpr.isInvalid()) 
return ExprError()32
;
423
1.67k
  addResultSemanticExpr(getExpr.get());
424
1.67k
425
1.67k
  return complete(syntacticBase);
426
1.67k
}
427
428
/// The basic skeleton for building a simple or compound
429
/// assignment operation.
430
ExprResult
431
PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc,
432
                                          BinaryOperatorKind opcode,
433
900
                                          Expr *LHS, Expr *RHS) {
434
900
  assert(BinaryOperator::isAssignmentOp(opcode));
435
900
436
900
  Expr *syntacticLHS = rebuildAndCaptureObject(LHS);
437
900
  OpaqueValueExpr *capturedRHS = capture(RHS);
438
900
439
900
  // In some very specific cases, semantic analysis of the RHS as an
440
900
  // expression may require it to be rewritten.  In these cases, we
441
900
  // cannot safely keep the OVE around.  Fortunately, we don't really
442
900
  // need to: we don't use this particular OVE in multiple places, and
443
900
  // no clients rely that closely on matching up expressions in the
444
900
  // semantic expression with expressions from the syntactic form.
445
900
  Expr *semanticRHS = capturedRHS;
446
900
  if (RHS->hasPlaceholderType() || 
isa<InitListExpr>(RHS)897
) {
447
7
    semanticRHS = RHS;
448
7
    Semantics.pop_back();
449
7
  }
450
900
451
900
  Expr *syntactic;
452
900
453
900
  ExprResult result;
454
900
  if (opcode == BO_Assign) {
455
863
    result = semanticRHS;
456
863
    syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
457
863
                                               opcode, capturedRHS->getType(),
458
863
                                               capturedRHS->getValueKind(),
459
863
                                               OK_Ordinary, opcLoc,
460
863
                                               FPOptions());
461
863
  } else {
462
37
    ExprResult opLHS = buildGet();
463
37
    if (opLHS.isInvalid()) 
return ExprError()0
;
464
37
465
37
    // Build an ordinary, non-compound operation.
466
37
    BinaryOperatorKind nonCompound =
467
37
      BinaryOperator::getOpForCompoundAssignment(opcode);
468
37
    result = S.BuildBinOp(Sc, opcLoc, nonCompound, opLHS.get(), semanticRHS);
469
37
    if (result.isInvalid()) 
return ExprError()0
;
470
37
471
37
    syntactic =
472
37
      new (S.Context) CompoundAssignOperator(syntacticLHS, capturedRHS, opcode,
473
37
                                             result.get()->getType(),
474
37
                                             result.get()->getValueKind(),
475
37
                                             OK_Ordinary,
476
37
                                             opLHS.get()->getType(),
477
37
                                             result.get()->getType(),
478
37
                                             opcLoc, FPOptions());
479
37
  }
480
900
481
900
  // The result of the assignment, if not void, is the value set into
482
900
  // the l-value.
483
900
  result = buildSet(result.get(), opcLoc, captureSetValueAsResult());
484
900
  if (result.isInvalid()) 
return ExprError()41
;
485
859
  addSemanticExpr(result.get());
486
859
  if (!captureSetValueAsResult() && 
!result.get()->getType()->isVoidType()61
&&
487
859
      
(26
result.get()->isTypeDependent()26
||
CanCaptureValue(result.get())17
))
488
26
    setResultToLastSemantic();
489
859
490
859
  return complete(syntactic);
491
859
}
492
493
/// The basic skeleton for building an increment or decrement
494
/// operation.
495
ExprResult
496
PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
497
                                      UnaryOperatorKind opcode,
498
41
                                      Expr *op) {
499
41
  assert(UnaryOperator::isIncrementDecrementOp(opcode));
500
41
501
41
  Expr *syntacticOp = rebuildAndCaptureObject(op);
502
41
503
41
  // Load the value.
504
41
  ExprResult result = buildGet();
505
41
  if (result.isInvalid()) 
return ExprError()1
;
506
40
507
40
  QualType resultType = result.get()->getType();
508
40
509
40
  // That's the postfix result.
510
40
  if (UnaryOperator::isPostfix(opcode) &&
511
40
      
(14
result.get()->isTypeDependent()14
||
CanCaptureValue(result.get())11
)) {
512
11
    result = capture(result.get());
513
11
    setResultToLastSemantic();
514
11
  }
515
40
516
40
  // Add or subtract a literal 1.
517
40
  llvm::APInt oneV(S.Context.getTypeSize(S.Context.IntTy), 1);
518
40
  Expr *one = IntegerLiteral::Create(S.Context, oneV, S.Context.IntTy,
519
40
                                     GenericLoc);
520
40
521
40
  if (UnaryOperator::isIncrementOp(opcode)) {
522
38
    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
523
38
  } else {
524
2
    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
525
2
  }
526
40
  if (result.isInvalid()) 
return ExprError()0
;
527
40
528
40
  // Store that back into the result.  The value stored is the result
529
40
  // of a prefix operation.
530
40
  result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode) &&
531
40
                                              
captureSetValueAsResult()26
);
532
40
  if (result.isInvalid()) 
return ExprError()0
;
533
40
  addSemanticExpr(result.get());
534
40
  if (UnaryOperator::isPrefix(opcode) && 
!captureSetValueAsResult()26
&&
535
40
      
!result.get()->getType()->isVoidType()7
&&
536
40
      
(6
result.get()->isTypeDependent()6
||
CanCaptureValue(result.get())5
))
537
6
    setResultToLastSemantic();
538
40
539
40
  UnaryOperator *syntactic = new (S.Context) UnaryOperator(
540
40
      syntacticOp, opcode, resultType, VK_LValue, OK_Ordinary, opcLoc,
541
40
      !resultType->isDependentType()
542
40
          ? S.Context.getTypeSize(resultType) >=
543
36
                S.Context.getTypeSize(S.Context.IntTy)
544
40
          : 
false4
);
545
40
  return complete(syntactic);
546
40
}
547
548
549
//===----------------------------------------------------------------------===//
550
//  Objective-C @property and implicit property references
551
//===----------------------------------------------------------------------===//
552
553
/// Look up a method in the receiver type of an Objective-C property
554
/// reference.
555
static ObjCMethodDecl *LookupMethodInReceiverType(Sema &S, Selector sel,
556
2.33k
                                            const ObjCPropertyRefExpr *PRE) {
557
2.33k
  if (PRE->isObjectReceiver()) {
558
2.26k
    const ObjCObjectPointerType *PT =
559
2.26k
      PRE->getBase()->getType()->castAs<ObjCObjectPointerType>();
560
2.26k
561
2.26k
    // Special case for 'self' in class method implementations.
562
2.26k
    if (PT->isObjCClassType() &&
563
2.26k
        
S.isSelfExpr(const_cast<Expr*>(PRE->getBase()))0
) {
564
0
      // This cast is safe because isSelfExpr is only true within
565
0
      // methods.
566
0
      ObjCMethodDecl *method =
567
0
        cast<ObjCMethodDecl>(S.CurContext->getNonClosureAncestor());
568
0
      return S.LookupMethodInObjectType(sel,
569
0
                 S.Context.getObjCInterfaceType(method->getClassInterface()),
570
0
                                        /*instance*/ false);
571
0
    }
572
2.26k
573
2.26k
    return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
574
2.26k
  }
575
69
576
69
  if (PRE->isSuperReceiver()) {
577
69
    if (const ObjCObjectPointerType *PT =
578
69
        PRE->getSuperReceiverType()->getAs<ObjCObjectPointerType>())
579
69
      return S.LookupMethodInObjectType(sel, PT->getPointeeType(), true);
580
0
581
0
    return S.LookupMethodInObjectType(sel, PRE->getSuperReceiverType(), false);
582
0
  }
583
0
584
0
  assert(PRE->isClassReceiver() && "Invalid expression");
585
0
  QualType IT = S.Context.getObjCInterfaceType(PRE->getClassReceiver());
586
0
  return S.LookupMethodInObjectType(sel, IT, false);
587
0
}
588
589
2.13k
bool ObjCPropertyOpBuilder::isWeakProperty() const {
590
2.13k
  QualType T;
591
2.13k
  if (RefExpr->isExplicitProperty()) {
592
1.66k
    const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
593
1.66k
    if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
594
202
      return true;
595
1.46k
596
1.46k
    T = Prop->getType();
597
1.46k
  } else 
if (468
Getter468
) {
598
369
    T = Getter->getReturnType();
599
369
  } else {
600
99
    return false;
601
99
  }
602
1.83k
603
1.83k
  return T.getObjCLifetime() == Qualifiers::OCL_Weak;
604
1.83k
}
605
606
1.51k
bool ObjCPropertyOpBuilder::findGetter() {
607
1.51k
  if (Getter) 
return true54
;
608
1.45k
609
1.45k
  // For implicit properties, just trust the lookup we already did.
610
1.45k
  if (RefExpr->isImplicitProperty()) {
611
372
    if ((Getter = RefExpr->getImplicitPropertyGetter())) {
612
370
      GetterSelector = Getter->getSelector();
613
370
      return true;
614
370
    }
615
2
    else {
616
2
      // Must build the getter selector the hard way.
617
2
      ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter();
618
2
      assert(setter && "both setter and getter are null - cannot happen");
619
2
      IdentifierInfo *setterName =
620
2
        setter->getSelector().getIdentifierInfoForSlot(0);
621
2
      IdentifierInfo *getterName =
622
2
          &S.Context.Idents.get(setterName->getName().substr(3));
623
2
      GetterSelector =
624
2
        S.PP.getSelectorTable().getNullarySelector(getterName);
625
2
      return false;
626
2
    }
627
1.08k
  }
628
1.08k
629
1.08k
  ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
630
1.08k
  Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
631
1.08k
  return (Getter != nullptr);
632
1.08k
}
633
634
/// Try to find the most accurate setter declaration for the property
635
/// reference.
636
///
637
/// \return true if a setter was found, in which case Setter
638
1.49k
bool ObjCPropertyOpBuilder::findSetter(bool warn) {
639
1.49k
  // For implicit properties, just trust the lookup we already did.
640
1.49k
  if (RefExpr->isImplicitProperty()) {
641
251
    if (ObjCMethodDecl *setter = RefExpr->getImplicitPropertySetter()) {
642
244
      Setter = setter;
643
244
      SetterSelector = setter->getSelector();
644
244
      return true;
645
244
    } else {
646
7
      IdentifierInfo *getterName =
647
7
        RefExpr->getImplicitPropertyGetter()->getSelector()
648
7
          .getIdentifierInfoForSlot(0);
649
7
      SetterSelector =
650
7
        SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
651
7
                                               S.PP.getSelectorTable(),
652
7
                                               getterName);
653
7
      return false;
654
7
    }
655
1.24k
  }
656
1.24k
657
1.24k
  // For explicit properties, this is more involved.
658
1.24k
  ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
659
1.24k
  SetterSelector = prop->getSetterName();
660
1.24k
661
1.24k
  // Do a normal method lookup first.
662
1.24k
  if (ObjCMethodDecl *setter =
663
1.23k
        LookupMethodInReceiverType(S, SetterSelector, RefExpr)) {
664
1.23k
    if (setter->isPropertyAccessor() && 
warn1.21k
)
665
608
      if (const ObjCInterfaceDecl *IFace =
666
561
          dyn_cast<ObjCInterfaceDecl>(setter->getDeclContext())) {
667
561
        StringRef thisPropertyName = prop->getName();
668
561
        // Try flipping the case of the first character.
669
561
        char front = thisPropertyName.front();
670
561
        front = isLowercase(front) ? 
toUppercase(front)534
:
toLowercase(front)27
;
671
561
        SmallString<100> PropertyName = thisPropertyName;
672
561
        PropertyName[0] = front;
673
561
        IdentifierInfo *AltMember = &S.PP.getIdentifierTable().get(PropertyName);
674
561
        if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(
675
4
                AltMember, prop->getQueryKind()))
676
4
          if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
677
4
            S.Diag(RefExpr->getExprLoc(), diag::err_property_setter_ambiguous_use)
678
4
              << prop << prop1 << setter->getSelector();
679
4
            S.Diag(prop->getLocation(), diag::note_property_declare);
680
4
            S.Diag(prop1->getLocation(), diag::note_property_declare);
681
4
          }
682
561
      }
683
1.23k
    Setter = setter;
684
1.23k
    return true;
685
1.23k
  }
686
6
687
6
  // That can fail in the somewhat crazy situation that we're
688
6
  // type-checking a message send within the @interface declaration
689
6
  // that declared the @property.  But it's not clear that that's
690
6
  // valuable to support.
691
6
692
6
  return false;
693
6
}
694
695
1
void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
696
1
  if (S.getCurLexicalContext()->isObjCContainer() &&
697
1
      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
698
1
      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
699
1
    if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
700
1
        S.Diag(RefExpr->getLocation(),
701
1
               diag::err_property_function_in_objc_container);
702
1
        S.Diag(prop->getLocation(), diag::note_property_declare);
703
1
    }
704
1
  }
705
1
}
706
707
/// Capture the base object of an Objective-C property expression.
708
2.14k
Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
709
2.14k
  assert(InstanceReceiver == nullptr);
710
2.14k
711
2.14k
  // If we have a base, capture it in an OVE and rebuild the syntactic
712
2.14k
  // form to use the OVE as its base.
713
2.14k
  if (RefExpr->isObjectReceiver()) {
714
1.90k
    InstanceReceiver = capture(RefExpr->getBase());
715
1.90k
    syntacticBase = Rebuilder(S, [=](Expr *, unsigned) -> Expr * {
716
1.90k
                      return InstanceReceiver;
717
1.90k
                    }).rebuild(syntacticBase);
718
1.90k
  }
719
2.14k
720
2.14k
  if (ObjCPropertyRefExpr *
721
2.14k
        refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
722
2.14k
    SyntacticRefExpr = refE;
723
2.14k
724
2.14k
  return syntacticBase;
725
2.14k
}
726
727
/// Load from an Objective-C property reference.
728
1.45k
ExprResult ObjCPropertyOpBuilder::buildGet() {
729
1.45k
  findGetter();
730
1.45k
  if (!Getter) {
731
1
    DiagnoseUnsupportedPropertyUse();
732
1
    return ExprError();
733
1
  }
734
1.45k
735
1.45k
  if (SyntacticRefExpr)
736
1.45k
    SyntacticRefExpr->setIsMessagingGetter();
737
1.45k
738
1.45k
  QualType receiverType = RefExpr->getReceiverType(S.Context);
739
1.45k
  if (!Getter->isImplicit())
740
337
    S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
741
1.45k
  // Build a message-send.
742
1.45k
  ExprResult msg;
743
1.45k
  if ((Getter->isInstanceMethod() && 
!RefExpr->isClassReceiver()1.29k
) ||
744
1.45k
      
RefExpr->isObjectReceiver()160
) {
745
1.29k
    assert(InstanceReceiver || RefExpr->isSuperReceiver());
746
1.29k
    msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
747
1.29k
                                         GenericLoc, Getter->getSelector(),
748
1.29k
                                         Getter, None);
749
1.29k
  } else {
750
157
    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
751
157
                                      GenericLoc, Getter->getSelector(),
752
157
                                      Getter, None);
753
157
  }
754
1.45k
  return msg;
755
1.45k
}
756
757
/// Store to an Objective-C property reference.
758
///
759
/// \param captureSetValueAsResult If true, capture the actual
760
///   value being set as the value of the property operation.
761
ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
762
740
                                           bool captureSetValueAsResult) {
763
740
  if (!findSetter(false)) {
764
0
    DiagnoseUnsupportedPropertyUse();
765
0
    return ExprError();
766
0
  }
767
740
768
740
  if (SyntacticRefExpr)
769
740
    SyntacticRefExpr->setIsMessagingSetter();
770
740
771
740
  QualType receiverType = RefExpr->getReceiverType(S.Context);
772
740
773
740
  // Use assignment constraints when possible; they give us better
774
740
  // diagnostics.  "When possible" basically means anything except a
775
740
  // C++ class type.
776
740
  if (!S.getLangOpts().CPlusPlus || 
!op->getType()->isRecordType()132
) {
777
720
    QualType paramType = (*Setter->param_begin())->getType()
778
720
                           .substObjCMemberType(
779
720
                             receiverType,
780
720
                             Setter->getDeclContext(),
781
720
                             ObjCSubstitutionContext::Parameter);
782
720
    if (!S.getLangOpts().CPlusPlus || 
!paramType->isRecordType()112
) {
783
717
      ExprResult opResult = op;
784
717
      Sema::AssignConvertType assignResult
785
717
        = S.CheckSingleAssignmentConstraints(paramType, opResult);
786
717
      if (opResult.isInvalid() ||
787
717
          S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
788
705
                                     op->getType(), opResult.get(),
789
705
                                     Sema::AA_Assigning))
790
12
        return ExprError();
791
705
792
705
      op = opResult.get();
793
705
      assert(op && "successful assignment left argument invalid?");
794
705
    }
795
720
  }
796
740
797
740
  // Arguments.
798
740
  Expr *args[] = { op };
799
728
800
728
  // Build a message-send.
801
728
  ExprResult msg;
802
728
  if (!Setter->isImplicit())
803
119
    S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
804
728
  if ((Setter->isInstanceMethod() && 
!RefExpr->isClassReceiver()704
) ||
805
728
      
RefExpr->isObjectReceiver()28
) {
806
701
    msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
807
701
                                         GenericLoc, SetterSelector, Setter,
808
701
                                         MultiExprArg(args, 1));
809
701
  } else {
810
27
    msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
811
27
                                      GenericLoc,
812
27
                                      SetterSelector, Setter,
813
27
                                      MultiExprArg(args, 1));
814
27
  }
815
728
816
728
  if (!msg.isInvalid() && captureSetValueAsResult) {
817
724
    ObjCMessageExpr *msgExpr =
818
724
      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
819
724
    Expr *arg = msgExpr->getArg(0);
820
724
    if (CanCaptureValue(arg))
821
714
      msgExpr->setArg(0, captureValueAsResult(arg));
822
724
  }
823
728
824
728
  return msg;
825
740
}
826
827
/// @property-specific behavior for doing lvalue-to-rvalue conversion.
828
1.41k
ExprResult ObjCPropertyOpBuilder::buildRValueOperation(Expr *op) {
829
1.41k
  // Explicit properties always have getters, but implicit ones don't.
830
1.41k
  // Check that before proceeding.
831
1.41k
  if (RefExpr->isImplicitProperty() && 
!RefExpr->getImplicitPropertyGetter()361
) {
832
12
    S.Diag(RefExpr->getLocation(), diag::err_getter_not_found)
833
12
        << RefExpr->getSourceRange();
834
12
    return ExprError();
835
12
  }
836
1.40k
837
1.40k
  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
838
1.40k
  if (result.isInvalid()) 
return ExprError()1
;
839
1.40k
840
1.40k
  if (RefExpr->isExplicitProperty() && 
!Getter->hasRelatedResultType()1.05k
)
841
1.04k
    S.DiagnosePropertyAccessorMismatch(RefExpr->getExplicitProperty(),
842
1.04k
                                       Getter, RefExpr->getLocation());
843
1.40k
844
1.40k
  // As a special case, if the method returns 'id', try to get
845
1.40k
  // a better type from the property.
846
1.40k
  if (RefExpr->isExplicitProperty() && 
result.get()->isRValue()1.05k
) {
847
1.03k
    QualType receiverType = RefExpr->getReceiverType(S.Context);
848
1.03k
    QualType propType = RefExpr->getExplicitProperty()
849
1.03k
                          ->getUsageType(receiverType);
850
1.03k
    if (result.get()->getType()->isObjCIdType()) {
851
153
      if (const ObjCObjectPointerType *ptr
852
153
            = propType->getAs<ObjCObjectPointerType>()) {
853
153
        if (!ptr->isObjCIdType())
854
4
          result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
855
153
      }
856
153
    }
857
1.03k
    if (propType.getObjCLifetime() == Qualifiers::OCL_Weak &&
858
1.03k
        !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
859
4
                           RefExpr->getLocation()))
860
4
      S.getCurFunction()->markSafeWeakUse(RefExpr);
861
1.03k
  }
862
1.40k
863
1.40k
  return result;
864
1.40k
}
865
866
/// Try to build this as a call to a getter that returns a reference.
867
///
868
/// \return true if it was possible, whether or not it actually
869
///   succeeded
870
bool ObjCPropertyOpBuilder::tryBuildGetOfReference(Expr *op,
871
13
                                                   ExprResult &result) {
872
13
  if (!S.getLangOpts().CPlusPlus) 
return false8
;
873
5
874
5
  findGetter();
875
5
  if (!Getter) {
876
0
    // The property has no setter and no getter! This can happen if the type is
877
0
    // invalid. Error have already been reported.
878
0
    result = ExprError();
879
0
    return true;
880
0
  }
881
5
882
5
  // Only do this if the getter returns an l-value reference type.
883
5
  QualType resultType = Getter->getReturnType();
884
5
  if (!resultType->isLValueReferenceType()) 
return false1
;
885
4
886
4
  result = buildRValueOperation(op);
887
4
  return true;
888
4
}
889
890
/// @property-specific behavior for doing assignments.
891
ExprResult
892
ObjCPropertyOpBuilder::buildAssignmentOperation(Scope *Sc,
893
                                                SourceLocation opcLoc,
894
                                                BinaryOperatorKind opcode,
895
728
                                                Expr *LHS, Expr *RHS) {
896
728
  assert(BinaryOperator::isAssignmentOp(opcode));
897
728
898
728
  // If there's no setter, we have no choice but to try to assign to
899
728
  // the result of the getter.
900
728
  if (!findSetter()) {
901
11
    ExprResult result;
902
11
    if (tryBuildGetOfReference(LHS, result)) {
903
4
      if (result.isInvalid()) 
return ExprError()0
;
904
4
      return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
905
4
    }
906
7
907
7
    // Otherwise, it's an error.
908
7
    S.Diag(opcLoc, diag::err_nosetter_property_assignment)
909
7
      << unsigned(RefExpr->isImplicitProperty())
910
7
      << SetterSelector
911
7
      << LHS->getSourceRange() << RHS->getSourceRange();
912
7
    return ExprError();
913
7
  }
914
717
915
717
  // If there is a setter, we definitely want to use it.
916
717
917
717
  // Verify that we can do a compound assignment.
918
717
  if (opcode != BO_Assign && 
!findGetter()27
) {
919
0
    S.Diag(opcLoc, diag::err_nogetter_property_compound_assignment)
920
0
      << LHS->getSourceRange() << RHS->getSourceRange();
921
0
    return ExprError();
922
0
  }
923
717
924
717
  ExprResult result =
925
717
    PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
926
717
  if (result.isInvalid()) 
return ExprError()12
;
927
705
928
705
  // Various warnings about property assignments in ARC.
929
705
  if (S.getLangOpts().ObjCAutoRefCount && 
InstanceReceiver147
) {
930
139
    S.checkRetainCycles(InstanceReceiver->getSourceExpr(), RHS);
931
139
    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
932
139
  }
933
705
934
705
  return result;
935
705
}
936
937
/// @property-specific behavior for doing increments and decrements.
938
ExprResult
939
ObjCPropertyOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
940
                                            UnaryOperatorKind opcode,
941
27
                                            Expr *op) {
942
27
  // If there's no setter, we have no choice but to try to assign to
943
27
  // the result of the getter.
944
27
  if (!findSetter()) {
945
2
    ExprResult result;
946
2
    if (tryBuildGetOfReference(op, result)) {
947
0
      if (result.isInvalid()) return ExprError();
948
0
      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
949
0
    }
950
2
951
2
    // Otherwise, it's an error.
952
2
    S.Diag(opcLoc, diag::err_nosetter_property_incdec)
953
2
      << unsigned(RefExpr->isImplicitProperty())
954
2
      << unsigned(UnaryOperator::isDecrementOp(opcode))
955
2
      << SetterSelector
956
2
      << op->getSourceRange();
957
2
    return ExprError();
958
2
  }
959
25
960
25
  // If there is a setter, we definitely want to use it.
961
25
962
25
  // We also need a getter.
963
25
  if (!findGetter()) {
964
2
    assert(RefExpr->isImplicitProperty());
965
2
    S.Diag(opcLoc, diag::err_nogetter_property_incdec)
966
2
      << unsigned(UnaryOperator::isDecrementOp(opcode))
967
2
      << GetterSelector
968
2
      << op->getSourceRange();
969
2
    return ExprError();
970
2
  }
971
23
972
23
  return PseudoOpBuilder::buildIncDecOperation(Sc, opcLoc, opcode, op);
973
23
}
974
975
2.13k
ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
976
2.13k
  if (isWeakProperty() && 
!S.isUnevaluatedContext()216
&&
977
2.13k
      !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
978
212
                         SyntacticForm->getBeginLoc()))
979
204
    S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr,
980
204
                                        SyntacticRefExpr->isMessagingGetter());
981
2.13k
982
2.13k
  return PseudoOpBuilder::complete(SyntacticForm);
983
2.13k
}
984
985
// ObjCSubscript build stuff.
986
//
987
988
/// objective-c subscripting-specific behavior for doing lvalue-to-rvalue
989
/// conversion.
990
/// FIXME. Remove this routine if it is proven that no additional
991
/// specifity is needed.
992
148
ExprResult ObjCSubscriptOpBuilder::buildRValueOperation(Expr *op) {
993
148
  ExprResult result = PseudoOpBuilder::buildRValueOperation(op);
994
148
  if (result.isInvalid()) 
return ExprError()22
;
995
126
  return result;
996
126
}
997
998
/// objective-c subscripting-specific  behavior for doing assignments.
999
ExprResult
1000
ObjCSubscriptOpBuilder::buildAssignmentOperation(Scope *Sc,
1001
                                                SourceLocation opcLoc,
1002
                                                BinaryOperatorKind opcode,
1003
114
                                                Expr *LHS, Expr *RHS) {
1004
114
  assert(BinaryOperator::isAssignmentOp(opcode));
1005
114
  // There must be a method to do the Index'ed assignment.
1006
114
  if (!findAtIndexSetter())
1007
14
    return ExprError();
1008
100
1009
100
  // Verify that we can do a compound assignment.
1010
100
  if (opcode != BO_Assign && 
!findAtIndexGetter()0
)
1011
0
    return ExprError();
1012
100
1013
100
  ExprResult result =
1014
100
  PseudoOpBuilder::buildAssignmentOperation(Sc, opcLoc, opcode, LHS, RHS);
1015
100
  if (result.isInvalid()) 
return ExprError()7
;
1016
93
1017
93
  // Various warnings about objc Index'ed assignments in ARC.
1018
93
  if (S.getLangOpts().ObjCAutoRefCount && 
InstanceBase6
) {
1019
6
    S.checkRetainCycles(InstanceBase->getSourceExpr(), RHS);
1020
6
    S.checkUnsafeExprAssigns(opcLoc, LHS, RHS);
1021
6
  }
1022
93
1023
93
  return result;
1024
93
}
1025
1026
/// Capture the base object of an Objective-C Index'ed expression.
1027
248
Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
1028
248
  assert(InstanceBase == nullptr);
1029
248
1030
248
  // Capture base expression in an OVE and rebuild the syntactic
1031
248
  // form to use the OVE as its base expression.
1032
248
  InstanceBase = capture(RefExpr->getBaseExpr());
1033
248
  InstanceKey = capture(RefExpr->getKeyExpr());
1034
248
1035
248
  syntacticBase =
1036
496
      Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * {
1037
496
        switch (Idx) {
1038
496
        case 0:
1039
248
          return InstanceBase;
1040
496
        case 1:
1041
248
          return InstanceKey;
1042
496
        default:
1043
0
          llvm_unreachable("Unexpected index for ObjCSubscriptExpr");
1044
496
        }
1045
496
      }).rebuild(syntacticBase);
1046
248
1047
248
  return syntacticBase;
1048
248
}
1049
1050
/// CheckSubscriptingKind - This routine decide what type
1051
/// of indexing represented by "FromE" is being done.
1052
Sema::ObjCSubscriptKind
1053
263
  Sema::CheckSubscriptingKind(Expr *FromE) {
1054
263
  // If the expression already has integral or enumeration type, we're golden.
1055
263
  QualType T = FromE->getType();
1056
263
  if (T->isIntegralOrEnumerationType())
1057
131
    return OS_Array;
1058
132
1059
132
  // If we don't have a class type in C++, there's no way we can get an
1060
132
  // expression of integral or enumeration type.
1061
132
  const RecordType *RecordTy = T->getAs<RecordType>();
1062
132
  if (!RecordTy &&
1063
132
      
(124
T->isObjCObjectPointerType()124
||
T->isVoidPointerType()24
))
1064
108
    // All other scalar cases are assumed to be dictionary indexing which
1065
108
    // caller handles, with diagnostics if needed.
1066
108
    return OS_Dictionary;
1067
24
  if (!getLangOpts().CPlusPlus ||
1068
24
      
!RecordTy10
||
RecordTy->isIncompleteType()8
) {
1069
16
    // No indexing can be done. Issue diagnostics and quit.
1070
16
    const Expr *IndexExpr = FromE->IgnoreParenImpCasts();
1071
16
    if (isa<StringLiteral>(IndexExpr))
1072
2
      Diag(FromE->getExprLoc(), diag::err_objc_subscript_pointer)
1073
2
        << T << FixItHint::CreateInsertion(FromE->getExprLoc(), "@");
1074
14
    else
1075
14
      Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
1076
14
        << T;
1077
16
    return OS_Error;
1078
16
  }
1079
8
1080
8
  // We must have a complete class type.
1081
8
  if (RequireCompleteType(FromE->getExprLoc(), T,
1082
8
                          diag::err_objc_index_incomplete_class_type, FromE))
1083
0
    return OS_Error;
1084
8
1085
8
  // Look for a conversion to an integral, enumeration type, or
1086
8
  // objective-C pointer type.
1087
8
  int NoIntegrals=0, NoObjCIdPointers=0;
1088
8
  SmallVector<CXXConversionDecl *, 4> ConversionDecls;
1089
8
1090
8
  for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl())
1091
9
                          ->getVisibleConversionFunctions()) {
1092
9
    if (CXXConversionDecl *Conversion =
1093
9
            dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
1094
9
      QualType CT = Conversion->getConversionType().getNonReferenceType();
1095
9
      if (CT->isIntegralOrEnumerationType()) {
1096
2
        ++NoIntegrals;
1097
2
        ConversionDecls.push_back(Conversion);
1098
2
      }
1099
7
      else if (CT->isObjCIdType() ||
CT->isBlockPointerType()4
) {
1100
7
        ++NoObjCIdPointers;
1101
7
        ConversionDecls.push_back(Conversion);
1102
7
      }
1103
9
    }
1104
9
  }
1105
8
  if (NoIntegrals ==1 && 
NoObjCIdPointers == 02
)
1106
1
    return OS_Array;
1107
7
  if (NoIntegrals == 0 && 
NoObjCIdPointers == 16
)
1108
6
    return OS_Dictionary;
1109
1
  if (NoIntegrals == 0 && 
NoObjCIdPointers == 00
) {
1110
0
    // No conversion function was found. Issue diagnostic and return.
1111
0
    Diag(FromE->getExprLoc(), diag::err_objc_subscript_type_conversion)
1112
0
      << FromE->getType();
1113
0
    return OS_Error;
1114
0
  }
1115
1
  Diag(FromE->getExprLoc(), diag::err_objc_multiple_subscript_type_conversion)
1116
1
      << FromE->getType();
1117
3
  for (unsigned int i = 0; i < ConversionDecls.size(); 
i++2
)
1118
2
    Diag(ConversionDecls[i]->getLocation(),
1119
2
         diag::note_conv_function_declared_at);
1120
1
1121
1
  return OS_Error;
1122
1
}
1123
1124
/// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
1125
/// objects used as dictionary subscript key objects.
1126
static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT,
1127
4
                                         Expr *Key) {
1128
4
  if (ContainerT.isNull())
1129
0
    return;
1130
4
  // dictionary subscripting.
1131
4
  // - (id)objectForKeyedSubscript:(id)key;
1132
4
  IdentifierInfo *KeyIdents[] = {
1133
4
    &S.Context.Idents.get("objectForKeyedSubscript")
1134
4
  };
1135
4
  Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1136
4
  ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT,
1137
4
                                                      true /*instance*/);
1138
4
  if (!Getter)
1139
0
    return;
1140
4
  QualType T = Getter->parameters()[0]->getType();
1141
4
  S.CheckObjCConversion(Key->getSourceRange(), T, Key,
1142
4
                        Sema::CCK_ImplicitConversion);
1143
4
}
1144
1145
148
bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
1146
148
  if (AtIndexGetter)
1147
0
    return true;
1148
148
1149
148
  Expr *BaseExpr = RefExpr->getBaseExpr();
1150
148
  QualType BaseT = BaseExpr->getType();
1151
148
1152
148
  QualType ResultType;
1153
148
  if (const ObjCObjectPointerType *PTy =
1154
148
      BaseT->getAs<ObjCObjectPointerType>()) {
1155
148
    ResultType = PTy->getPointeeType();
1156
148
  }
1157
148
  Sema::ObjCSubscriptKind Res =
1158
148
    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
1159
148
  if (Res == Sema::OS_Error) {
1160
11
    if (S.getLangOpts().ObjCAutoRefCount)
1161
2
      CheckKeyForObjCARCConversion(S, ResultType,
1162
2
                                   RefExpr->getKeyExpr());
1163
11
    return false;
1164
11
  }
1165
137
  bool arrayRef = (Res == Sema::OS_Array);
1166
137
1167
137
  if (ResultType.isNull()) {
1168
0
    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
1169
0
      << BaseExpr->getType() << arrayRef;
1170
0
    return false;
1171
0
  }
1172
137
  if (!arrayRef) {
1173
60
    // dictionary subscripting.
1174
60
    // - (id)objectForKeyedSubscript:(id)key;
1175
60
    IdentifierInfo *KeyIdents[] = {
1176
60
      &S.Context.Idents.get("objectForKeyedSubscript")
1177
60
    };
1178
60
    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1179
60
  }
1180
77
  else {
1181
77
    // - (id)objectAtIndexedSubscript:(size_t)index;
1182
77
    IdentifierInfo *KeyIdents[] = {
1183
77
      &S.Context.Idents.get("objectAtIndexedSubscript")
1184
77
    };
1185
77
1186
77
    AtIndexGetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
1187
77
  }
1188
137
1189
137
  AtIndexGetter = S.LookupMethodInObjectType(AtIndexGetterSelector, ResultType,
1190
137
                                             true /*instance*/);
1191
137
1192
137
  if (!AtIndexGetter && 
S.getLangOpts().DebuggerObjCLiteral17
) {
1193
0
    AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
1194
0
                           SourceLocation(), AtIndexGetterSelector,
1195
0
                           S.Context.getObjCIdType() /*ReturnType*/,
1196
0
                           nullptr /*TypeSourceInfo */,
1197
0
                           S.Context.getTranslationUnitDecl(),
1198
0
                           true /*Instance*/, false/*isVariadic*/,
1199
0
                           /*isPropertyAccessor=*/false,
1200
0
                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1201
0
                           ObjCMethodDecl::Required,
1202
0
                           false);
1203
0
    ParmVarDecl *Argument = ParmVarDecl::Create(S.Context, AtIndexGetter,
1204
0
                                                SourceLocation(), SourceLocation(),
1205
0
                                                arrayRef ? &S.Context.Idents.get("index")
1206
0
                                                         : &S.Context.Idents.get("key"),
1207
0
                                                arrayRef ? S.Context.UnsignedLongTy
1208
0
                                                         : S.Context.getObjCIdType(),
1209
0
                                                /*TInfo=*/nullptr,
1210
0
                                                SC_None,
1211
0
                                                nullptr);
1212
0
    AtIndexGetter->setMethodParams(S.Context, Argument, None);
1213
0
  }
1214
137
1215
137
  if (!AtIndexGetter) {
1216
17
    if (!BaseT->isObjCIdType()) {
1217
7
      S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_method_not_found)
1218
7
      << BaseExpr->getType() << 0 << arrayRef;
1219
7
      return false;
1220
7
    }
1221
10
    AtIndexGetter =
1222
10
      S.LookupInstanceMethodInGlobalPool(AtIndexGetterSelector,
1223
10
                                         RefExpr->getSourceRange(),
1224
10
                                         true);
1225
10
  }
1226
137
1227
137
  
if (130
AtIndexGetter130
) {
1228
129
    QualType T = AtIndexGetter->parameters()[0]->getType();
1229
129
    if ((arrayRef && 
!T->isIntegralOrEnumerationType()70
) ||
1230
129
        
(128
!arrayRef128
&&
!T->isObjCObjectPointerType()59
)) {
1231
2
      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1232
2
             arrayRef ? 
diag::err_objc_subscript_index_type1
1233
2
                      : 
diag::err_objc_subscript_key_type1
) << T;
1234
2
      S.Diag(AtIndexGetter->parameters()[0]->getLocation(),
1235
2
             diag::note_parameter_type) << T;
1236
2
      return false;
1237
2
    }
1238
127
    QualType R = AtIndexGetter->getReturnType();
1239
127
    if (!R->isObjCObjectPointerType()) {
1240
2
      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1241
2
             diag::err_objc_indexing_method_result_type) << R << arrayRef;
1242
2
      S.Diag(AtIndexGetter->getLocation(), diag::note_method_declared_at) <<
1243
2
        AtIndexGetter->getDeclName();
1244
2
    }
1245
127
  }
1246
130
  
return true128
;
1247
130
}
1248
1249
214
bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
1250
214
  if (AtIndexSetter)
1251
99
    return true;
1252
115
1253
115
  Expr *BaseExpr = RefExpr->getBaseExpr();
1254
115
  QualType BaseT = BaseExpr->getType();
1255
115
1256
115
  QualType ResultType;
1257
115
  if (const ObjCObjectPointerType *PTy =
1258
115
      BaseT->getAs<ObjCObjectPointerType>()) {
1259
115
    ResultType = PTy->getPointeeType();
1260
115
  }
1261
115
1262
115
  Sema::ObjCSubscriptKind Res =
1263
115
    S.CheckSubscriptingKind(RefExpr->getKeyExpr());
1264
115
  if (Res == Sema::OS_Error) {
1265
6
    if (S.getLangOpts().ObjCAutoRefCount)
1266
2
      CheckKeyForObjCARCConversion(S, ResultType,
1267
2
                                   RefExpr->getKeyExpr());
1268
6
    return false;
1269
6
  }
1270
109
  bool arrayRef = (Res == Sema::OS_Array);
1271
109
1272
109
  if (ResultType.isNull()) {
1273
0
    S.Diag(BaseExpr->getExprLoc(), diag::err_objc_subscript_base_type)
1274
0
      << BaseExpr->getType() << arrayRef;
1275
0
    return false;
1276
0
  }
1277
109
1278
109
  if (!arrayRef) {
1279
54
    // dictionary subscripting.
1280
54
    // - (void)setObject:(id)object forKeyedSubscript:(id)key;
1281
54
    IdentifierInfo *KeyIdents[] = {
1282
54
      &S.Context.Idents.get("setObject"),
1283
54
      &S.Context.Idents.get("forKeyedSubscript")
1284
54
    };
1285
54
    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1286
54
  }
1287
55
  else {
1288
55
    // - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1289
55
    IdentifierInfo *KeyIdents[] = {
1290
55
      &S.Context.Idents.get("setObject"),
1291
55
      &S.Context.Idents.get("atIndexedSubscript")
1292
55
    };
1293
55
    AtIndexSetterSelector = S.Context.Selectors.getSelector(2, KeyIdents);
1294
55
  }
1295
109
  AtIndexSetter = S.LookupMethodInObjectType(AtIndexSetterSelector, ResultType,
1296
109
                                             true /*instance*/);
1297
109
1298
109
  if (!AtIndexSetter && 
S.getLangOpts().DebuggerObjCLiteral11
) {
1299
0
    TypeSourceInfo *ReturnTInfo = nullptr;
1300
0
    QualType ReturnType = S.Context.VoidTy;
1301
0
    AtIndexSetter = ObjCMethodDecl::Create(
1302
0
        S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector,
1303
0
        ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(),
1304
0
        true /*Instance*/, false /*isVariadic*/,
1305
0
        /*isPropertyAccessor=*/false,
1306
0
        /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
1307
0
        ObjCMethodDecl::Required, false);
1308
0
    SmallVector<ParmVarDecl *, 2> Params;
1309
0
    ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
1310
0
                                                SourceLocation(), SourceLocation(),
1311
0
                                                &S.Context.Idents.get("object"),
1312
0
                                                S.Context.getObjCIdType(),
1313
0
                                                /*TInfo=*/nullptr,
1314
0
                                                SC_None,
1315
0
                                                nullptr);
1316
0
    Params.push_back(object);
1317
0
    ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
1318
0
                                                SourceLocation(), SourceLocation(),
1319
0
                                                arrayRef ?  &S.Context.Idents.get("index")
1320
0
                                                         :  &S.Context.Idents.get("key"),
1321
0
                                                arrayRef ? S.Context.UnsignedLongTy
1322
0
                                                         : S.Context.getObjCIdType(),
1323
0
                                                /*TInfo=*/nullptr,
1324
0
                                                SC_None,
1325
0
                                                nullptr);
1326
0
    Params.push_back(key);
1327
0
    AtIndexSetter->setMethodParams(S.Context, Params, None);
1328
0
  }
1329
109
1330
109
  if (!AtIndexSetter) {
1331
11
    if (!BaseT->isObjCIdType()) {
1332
4
      S.Diag(BaseExpr->getExprLoc(),
1333
4
             diag::err_objc_subscript_method_not_found)
1334
4
      << BaseExpr->getType() << 1 << arrayRef;
1335
4
      return false;
1336
4
    }
1337
7
    AtIndexSetter =
1338
7
      S.LookupInstanceMethodInGlobalPool(AtIndexSetterSelector,
1339
7
                                         RefExpr->getSourceRange(),
1340
7
                                         true);
1341
7
  }
1342
109
1343
109
  bool err = false;
1344
105
  if (AtIndexSetter && 
arrayRef103
) {
1345
49
    QualType T = AtIndexSetter->parameters()[1]->getType();
1346
49
    if (!T->isIntegralOrEnumerationType()) {
1347
1
      S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1348
1
             diag::err_objc_subscript_index_type) << T;
1349
1
      S.Diag(AtIndexSetter->parameters()[1]->getLocation(),
1350
1
             diag::note_parameter_type) << T;
1351
1
      err = true;
1352
1
    }
1353
49
    T = AtIndexSetter->parameters()[0]->getType();
1354
49
    if (!T->isObjCObjectPointerType()) {
1355
2
      S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1356
2
             diag::err_objc_subscript_object_type) << T << arrayRef;
1357
2
      S.Diag(AtIndexSetter->parameters()[0]->getLocation(),
1358
2
             diag::note_parameter_type) << T;
1359
2
      err = true;
1360
2
    }
1361
49
  }
1362
56
  else if (AtIndexSetter && 
!arrayRef54
)
1363
162
    
for (unsigned i=0; 54
i <2;
i++108
) {
1364
108
      QualType T = AtIndexSetter->parameters()[i]->getType();
1365
108
      if (!T->isObjCObjectPointerType()) {
1366
3
        if (i == 1)
1367
1
          S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
1368
1
                 diag::err_objc_subscript_key_type) << T;
1369
2
        else
1370
2
          S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
1371
2
                 diag::err_objc_subscript_dic_object_type) << T;
1372
3
        S.Diag(AtIndexSetter->parameters()[i]->getLocation(),
1373
3
               diag::note_parameter_type) << T;
1374
3
        err = true;
1375
3
      }
1376
108
    }
1377
105
1378
105
  return !err;
1379
109
}
1380
1381
// Get the object at "Index" position in the container.
1382
// [BaseExpr objectAtIndexedSubscript : IndexExpr];
1383
148
ExprResult ObjCSubscriptOpBuilder::buildGet() {
1384
148
  if (!findAtIndexGetter())
1385
20
    return ExprError();
1386
128
1387
128
  QualType receiverType = InstanceBase->getType();
1388
128
1389
128
  // Build a message-send.
1390
128
  ExprResult msg;
1391
128
  Expr *Index = InstanceKey;
1392
128
1393
128
  // Arguments.
1394
128
  Expr *args[] = { Index };
1395
128
  assert(InstanceBase);
1396
128
  if (AtIndexGetter)
1397
127
    S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
1398
128
  msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1399
128
                                       GenericLoc,
1400
128
                                       AtIndexGetterSelector, AtIndexGetter,
1401
128
                                       MultiExprArg(args, 1));
1402
128
  return msg;
1403
128
}
1404
1405
/// Store into the container the "op" object at "Index"'ed location
1406
/// by building this messaging expression:
1407
/// - (void)setObject:(id)object atIndexedSubscript:(NSInteger)index;
1408
/// \param captureSetValueAsResult If true, capture the actual
1409
///   value being set as the value of the property operation.
1410
ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
1411
100
                                           bool captureSetValueAsResult) {
1412
100
  if (!findAtIndexSetter())
1413
0
    return ExprError();
1414
100
  if (AtIndexSetter)
1415
99
    S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
1416
100
  QualType receiverType = InstanceBase->getType();
1417
100
  Expr *Index = InstanceKey;
1418
100
1419
100
  // Arguments.
1420
100
  Expr *args[] = { op, Index };
1421
100
1422
100
  // Build a message-send.
1423
100
  ExprResult msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
1424
100
                                                  GenericLoc,
1425
100
                                                  AtIndexSetterSelector,
1426
100
                                                  AtIndexSetter,
1427
100
                                                  MultiExprArg(args, 2));
1428
100
1429
100
  if (!msg.isInvalid() && 
captureSetValueAsResult93
) {
1430
93
    ObjCMessageExpr *msgExpr =
1431
93
      cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
1432
93
    Expr *arg = msgExpr->getArg(0);
1433
93
    if (CanCaptureValue(arg))
1434
93
      msgExpr->setArg(0, captureValueAsResult(arg));
1435
93
  }
1436
100
1437
100
  return msg;
1438
100
}
1439
1440
//===----------------------------------------------------------------------===//
1441
//  MSVC __declspec(property) references
1442
//===----------------------------------------------------------------------===//
1443
1444
MSPropertyRefExpr *
1445
72
MSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr *E) {
1446
72
  CallArgs.insert(CallArgs.begin(), E->getIdx());
1447
72
  Expr *Base = E->getBase()->IgnoreParens();
1448
144
  while (auto *MSPropSubscript = dyn_cast<MSPropertySubscriptExpr>(Base)) {
1449
72
    CallArgs.insert(CallArgs.begin(), MSPropSubscript->getIdx());
1450
72
    Base = MSPropSubscript->getBase()->IgnoreParens();
1451
72
  }
1452
72
  return cast<MSPropertyRefExpr>(Base);
1453
72
}
1454
1455
250
Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
1456
250
  InstanceBase = capture(RefExpr->getBaseExpr());
1457
250
  llvm::for_each(CallArgs, [this](Expr *&Arg) 
{ Arg = capture(Arg); }144
);
1458
394
  syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * {
1459
394
                    switch (Idx) {
1460
394
                    case 0:
1461
250
                      return InstanceBase;
1462
394
                    default:
1463
144
                      assert(Idx <= CallArgs.size());
1464
144
                      return CallArgs[Idx - 1];
1465
394
                    }
1466
394
                  }).rebuild(syntacticBase);
1467
250
1468
250
  return syntacticBase;
1469
250
}
1470
1471
177
ExprResult MSPropertyOpBuilder::buildGet() {
1472
177
  if (!RefExpr->getPropertyDecl()->hasGetter()) {
1473
3
    S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1474
3
      << 0 /* getter */ << RefExpr->getPropertyDecl();
1475
3
    return ExprError();
1476
3
  }
1477
174
1478
174
  UnqualifiedId GetterName;
1479
174
  IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
1480
174
  GetterName.setIdentifier(II, RefExpr->getMemberLoc());
1481
174
  CXXScopeSpec SS;
1482
174
  SS.Adopt(RefExpr->getQualifierLoc());
1483
174
  ExprResult GetterExpr =
1484
174
      S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(),
1485
174
                              RefExpr->isArrow() ? 
tok::arrow92
:
tok::period82
, SS,
1486
174
                              SourceLocation(), GetterName, nullptr);
1487
174
  if (GetterExpr.isInvalid()) {
1488
3
    S.Diag(RefExpr->getMemberLoc(),
1489
3
           diag::err_cannot_find_suitable_accessor) << 0 /* getter */
1490
3
      << RefExpr->getPropertyDecl();
1491
3
    return ExprError();
1492
3
  }
1493
171
1494
171
  return S.BuildCallExpr(S.getCurScope(), GetterExpr.get(),
1495
171
                         RefExpr->getSourceRange().getBegin(), CallArgs,
1496
171
                         RefExpr->getSourceRange().getEnd());
1497
171
}
1498
1499
ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
1500
100
                                         bool captureSetValueAsResult) {
1501
100
  if (!RefExpr->getPropertyDecl()->hasSetter()) {
1502
16
    S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
1503
16
      << 1 /* setter */ << RefExpr->getPropertyDecl();
1504
16
    return ExprError();
1505
16
  }
1506
84
1507
84
  UnqualifiedId SetterName;
1508
84
  IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
1509
84
  SetterName.setIdentifier(II, RefExpr->getMemberLoc());
1510
84
  CXXScopeSpec SS;
1511
84
  SS.Adopt(RefExpr->getQualifierLoc());
1512
84
  ExprResult SetterExpr =
1513
84
      S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(),
1514
84
                              RefExpr->isArrow() ? 
tok::arrow58
:
tok::period26
, SS,
1515
84
                              SourceLocation(), SetterName, nullptr);
1516
84
  if (SetterExpr.isInvalid()) {
1517
3
    S.Diag(RefExpr->getMemberLoc(),
1518
3
           diag::err_cannot_find_suitable_accessor) << 1 /* setter */
1519
3
      << RefExpr->getPropertyDecl();
1520
3
    return ExprError();
1521
3
  }
1522
81
1523
81
  SmallVector<Expr*, 4> ArgExprs;
1524
81
  ArgExprs.append(CallArgs.begin(), CallArgs.end());
1525
81
  ArgExprs.push_back(op);
1526
81
  return S.BuildCallExpr(S.getCurScope(), SetterExpr.get(),
1527
81
                         RefExpr->getSourceRange().getBegin(), ArgExprs,
1528
81
                         op->getSourceRange().getEnd());
1529
81
}
1530
1531
//===----------------------------------------------------------------------===//
1532
//  General Sema routines.
1533
//===----------------------------------------------------------------------===//
1534
1535
1.71k
ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
1536
1.71k
  Expr *opaqueRef = E->IgnoreParens();
1537
1.71k
  if (ObjCPropertyRefExpr *refExpr
1538
1.41k
        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1539
1.41k
    ObjCPropertyOpBuilder builder(*this, refExpr, true);
1540
1.41k
    return builder.buildRValueOperation(E);
1541
1.41k
  }
1542
297
  else if (ObjCSubscriptRefExpr *refExpr
1543
148
           = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1544
148
    ObjCSubscriptOpBuilder builder(*this, refExpr, true);
1545
148
    return builder.buildRValueOperation(E);
1546
149
  } else if (MSPropertyRefExpr *refExpr
1547
118
             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1548
118
    MSPropertyOpBuilder builder(*this, refExpr, true);
1549
118
    return builder.buildRValueOperation(E);
1550
118
  } else 
if (MSPropertySubscriptExpr *31
RefExpr31
=
1551
31
                 dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1552
31
    MSPropertyOpBuilder Builder(*this, RefExpr, true);
1553
31
    return Builder.buildRValueOperation(E);
1554
31
  } else {
1555
0
    llvm_unreachable("unknown pseudo-object kind!");
1556
0
  }
1557
1.71k
}
1558
1559
/// Check an increment or decrement of a pseudo-object expression.
1560
ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
1561
48
                                         UnaryOperatorKind opcode, Expr *op) {
1562
48
  // Do nothing if the operand is dependent.
1563
48
  if (op->isTypeDependent())
1564
0
    return new (Context) UnaryOperator(op, opcode, Context.DependentTy,
1565
0
                                       VK_RValue, OK_Ordinary, opcLoc, false);
1566
48
1567
48
  assert(UnaryOperator::isIncrementDecrementOp(opcode));
1568
48
  Expr *opaqueRef = op->IgnoreParens();
1569
48
  if (ObjCPropertyRefExpr *refExpr
1570
27
        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1571
27
    ObjCPropertyOpBuilder builder(*this, refExpr, false);
1572
27
    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1573
27
  } else 
if (21
isa<ObjCSubscriptRefExpr>(opaqueRef)21
) {
1574
3
    Diag(opcLoc, diag::err_illegal_container_subscripting_op);
1575
3
    return ExprError();
1576
18
  } else if (MSPropertyRefExpr *refExpr
1577
11
             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1578
11
    MSPropertyOpBuilder builder(*this, refExpr, false);
1579
11
    return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1580
11
  } else 
if (MSPropertySubscriptExpr *7
RefExpr7
1581
7
             = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1582
7
    MSPropertyOpBuilder Builder(*this, RefExpr, false);
1583
7
    return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
1584
7
  } else {
1585
0
    llvm_unreachable("unknown pseudo-object kind!");
1586
0
  }
1587
48
}
1588
1589
ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
1590
                                             BinaryOperatorKind opcode,
1591
931
                                             Expr *LHS, Expr *RHS) {
1592
931
  // Do nothing if either argument is dependent.
1593
931
  if (LHS->isTypeDependent() || RHS->isTypeDependent())
1594
6
    return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
1595
6
                                        VK_RValue, OK_Ordinary, opcLoc,
1596
6
                                        FPOptions());
1597
925
1598
925
  // Filter out non-overload placeholder types in the RHS.
1599
925
  if (RHS->getType()->isNonOverloadPlaceholderType()) {
1600
56
    ExprResult result = CheckPlaceholderExpr(RHS);
1601
56
    if (result.isInvalid()) 
return ExprError()0
;
1602
56
    RHS = result.get();
1603
56
  }
1604
925
1605
925
  bool IsSimpleAssign = opcode == BO_Assign;
1606
925
  Expr *opaqueRef = LHS->IgnoreParens();
1607
925
  if (ObjCPropertyRefExpr *refExpr
1608
728
        = dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
1609
728
    ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
1610
728
    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1611
728
  } else 
if (ObjCSubscriptRefExpr *197
refExpr197
1612
114
             = dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
1613
114
    ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign);
1614
114
    return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1615
114
  } else 
if (MSPropertyRefExpr *83
refExpr83
1616
49
             = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
1617
49
      MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
1618
49
      return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1619
49
  } else 
if (MSPropertySubscriptExpr *34
RefExpr34
1620
34
             = dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
1621
34
      MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign);
1622
34
      return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
1623
34
  } else {
1624
0
    llvm_unreachable("unknown pseudo-object kind!");
1625
0
  }
1626
925
}
1627
1628
/// Given a pseudo-object reference, rebuild it without the opaque
1629
/// values.  Basically, undo the behavior of rebuildAndCaptureObject.
1630
/// This should never operate in-place.
1631
40
static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
1632
40
  return Rebuilder(S,
1633
65
                   [=](Expr *E, unsigned) -> Expr * {
1634
65
                     return cast<OpaqueValueExpr>(E)->getSourceExpr();
1635
65
                   })
1636
40
      .rebuild(E);
1637
40
}
1638
1639
/// Given a pseudo-object expression, recreate what it looks like
1640
/// syntactically without the attendant OpaqueValueExprs.
1641
///
1642
/// This is a hack which should be removed when TreeTransform is
1643
/// capable of rebuilding a tree without stripping implicit
1644
/// operations.
1645
40
Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) {
1646
40
  Expr *syntax = E->getSyntacticForm();
1647
40
  if (UnaryOperator *uop = dyn_cast<UnaryOperator>(syntax)) {
1648
4
    Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr());
1649
4
    return new (Context) UnaryOperator(
1650
4
        op, uop->getOpcode(), uop->getType(), uop->getValueKind(),
1651
4
        uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow());
1652
36
  } else if (CompoundAssignOperator *cop
1653
5
               = dyn_cast<CompoundAssignOperator>(syntax)) {
1654
5
    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS());
1655
5
    Expr *rhs = cast<OpaqueValueExpr>(cop->getRHS())->getSourceExpr();
1656
5
    return new (Context) CompoundAssignOperator(lhs, rhs, cop->getOpcode(),
1657
5
                                                cop->getType(),
1658
5
                                                cop->getValueKind(),
1659
5
                                                cop->getObjectKind(),
1660
5
                                                cop->getComputationLHSType(),
1661
5
                                                cop->getComputationResultType(),
1662
5
                                                cop->getOperatorLoc(),
1663
5
                                                FPOptions());
1664
31
  } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
1665
13
    Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
1666
13
    Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
1667
13
    return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
1668
13
                                        bop->getType(), bop->getValueKind(),
1669
13
                                        bop->getObjectKind(),
1670
13
                                        bop->getOperatorLoc(), FPOptions());
1671
18
  } else {
1672
18
    assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
1673
18
    return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
1674
18
  }
1675
40
}