Coverage Report

Created: 2017-10-03 07:32

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