Coverage Report

Created: 2018-07-22 10:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Analysis/ConstructionContext.h
Line
Count
Source (jump to first uncovered line)
1
//===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===//
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 defines the ConstructionContext class and its sub-classes,
11
// which represent various different ways of constructing C++ objects
12
// with the additional information the users may want to know about
13
// the constructor.
14
//
15
//===----------------------------------------------------------------------===//
16
17
#ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
18
#define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
19
20
#include "clang/Analysis/Support/BumpVector.h"
21
#include "clang/AST/ExprCXX.h"
22
23
namespace clang {
24
25
/// Construction context is a linked list of multiple layers. Layers are
26
/// created gradually while traversing the AST, and layers that represent
27
/// the outmost AST nodes are built first, while the node that immediately
28
/// contains the constructor would be built last and capture the previous
29
/// layers as its parents. Construction context captures the last layer
30
/// (which has links to the previous layers) and classifies the seemingly
31
/// arbitrary chain of layers into one of the possible ways of constructing
32
/// an object in C++ for user-friendly experience.
33
class ConstructionContextLayer {
34
public:
35
  typedef llvm::PointerUnion<Stmt *, CXXCtorInitializer *> TriggerTy;
36
37
private:
38
  /// The construction site - the statement that triggered the construction
39
  /// for one of its parts. For instance, stack variable declaration statement
40
  /// triggers construction of itself or its elements if it's an array,
41
  /// new-expression triggers construction of the newly allocated object(s).
42
  TriggerTy Trigger;
43
44
  /// Sometimes a single trigger is not enough to describe the construction
45
  /// site. In this case we'd have a chain of "partial" construction context
46
  /// layers.
47
  /// Some examples:
48
  /// - A constructor within in an aggregate initializer list within a variable
49
  ///   would have a construction context of the initializer list with
50
  ///   the parent construction context of a variable.
51
  /// - A constructor for a temporary that needs to be both destroyed
52
  ///   and materialized into an elidable copy constructor would have a
53
  ///   construction context of a CXXBindTemporaryExpr with the parent
54
  ///   construction context of a MaterializeTemproraryExpr.
55
  /// Not all of these are currently supported.
56
  const ConstructionContextLayer *Parent = nullptr;
57
58
  ConstructionContextLayer(TriggerTy Trigger,
59
                          const ConstructionContextLayer *Parent)
60
1.97M
      : Trigger(Trigger), Parent(Parent) {}
61
62
public:
63
  static const ConstructionContextLayer *
64
  create(BumpVectorContext &C, TriggerTy Trigger,
65
         const ConstructionContextLayer *Parent = nullptr);
66
67
5.53k
  const ConstructionContextLayer *getParent() const { return Parent; }
68
  bool isLast() const { return !Parent; }
69
70
16.1k
  const Stmt *getTriggerStmt() const {
71
16.1k
    return Trigger.dyn_cast<Stmt *>();
72
16.1k
  }
73
74
2.95k
  const CXXCtorInitializer *getTriggerInit() const {
75
2.95k
    return Trigger.dyn_cast<CXXCtorInitializer *>();
76
2.95k
  }
77
78
  /// Returns true if these layers are equal as individual layers, even if
79
  /// their parents are different.
80
0
  bool isSameLayer(const ConstructionContextLayer *Other) const {
81
0
    assert(Other);
82
0
    return (Trigger == Other->Trigger);
83
0
  }
84
85
  /// See if Other is a proper initial segment of this construction context
86
  /// in terms of the parent chain - i.e. a few first parents coincide and
87
  /// then the other context terminates but our context goes further - i.e.,
88
  /// we are providing the same context that the other context provides,
89
  /// and a bit more above that.
90
  bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const;
91
};
92
93
94
/// ConstructionContext's subclasses describe different ways of constructing
95
/// an object in C++. The context re-captures the essential parent AST nodes
96
/// of the CXXConstructExpr it is assigned to and presents these nodes
97
/// through easy-to-understand accessor methods.
98
class ConstructionContext {
99
public:
100
  enum Kind {
101
    SimpleVariableKind,
102
    CXX17ElidedCopyVariableKind,
103
    VARIABLE_BEGIN = SimpleVariableKind,
104
    VARIABLE_END = CXX17ElidedCopyVariableKind,
105
    SimpleConstructorInitializerKind,
106
    CXX17ElidedCopyConstructorInitializerKind,
107
    INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
108
    INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
109
    NewAllocatedObjectKind,
110
    SimpleTemporaryObjectKind,
111
    ElidedTemporaryObjectKind,
112
    TEMPORARY_BEGIN = SimpleTemporaryObjectKind,
113
    TEMPORARY_END = ElidedTemporaryObjectKind,
114
    SimpleReturnedValueKind,
115
    CXX17ElidedCopyReturnedValueKind,
116
    RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
117
    RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind
118
  };
119
120
protected:
121
  Kind K;
122
123
  // Do not make public! These need to only be constructed
124
  // via createFromLayers().
125
9.71k
  explicit ConstructionContext(Kind K) : K(K) {}
126
127
private:
128
  // A helper function for constructing an instance into a bump vector context.
129
  template <typename T, typename... ArgTypes>
130
9.71k
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
9.71k
    auto *CC = C.getAllocator().Allocate<T>();
132
9.71k
    return new (CC) T(Args...);
133
9.71k
  }
clang::SimpleVariableConstructionContext* clang::ConstructionContext::create<clang::SimpleVariableConstructionContext, clang::DeclStmt const*>(clang::BumpVectorContext&, clang::DeclStmt const*)
Line
Count
Source
130
4.04k
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
4.04k
    auto *CC = C.getAllocator().Allocate<T>();
132
4.04k
    return new (CC) T(Args...);
133
4.04k
  }
clang::NewAllocatedObjectConstructionContext* clang::ConstructionContext::create<clang::NewAllocatedObjectConstructionContext, clang::CXXNewExpr const*>(clang::BumpVectorContext&, clang::CXXNewExpr const*)
Line
Count
Source
130
685
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
685
    auto *CC = C.getAllocator().Allocate<T>();
132
685
    return new (CC) T(Args...);
133
685
  }
clang::CXX17ElidedCopyConstructorInitializerConstructionContext* clang::ConstructionContext::create<clang::CXX17ElidedCopyConstructorInitializerConstructionContext, clang::CXXCtorInitializer const*, clang::CXXBindTemporaryExpr const*>(clang::BumpVectorContext&, clang::CXXCtorInitializer const*, clang::CXXBindTemporaryExpr const*)
Line
Count
Source
130
12
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
12
    auto *CC = C.getAllocator().Allocate<T>();
132
12
    return new (CC) T(Args...);
133
12
  }
clang::SimpleTemporaryObjectConstructionContext* clang::ConstructionContext::create<clang::SimpleTemporaryObjectConstructionContext, clang::CXXBindTemporaryExpr const*, clang::MaterializeTemporaryExpr const*>(clang::BumpVectorContext&, clang::CXXBindTemporaryExpr const*, clang::MaterializeTemporaryExpr const*)
Line
Count
Source
130
878
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
878
    auto *CC = C.getAllocator().Allocate<T>();
132
878
    return new (CC) T(Args...);
133
878
  }
clang::ElidedTemporaryObjectConstructionContext* clang::ConstructionContext::create<clang::ElidedTemporaryObjectConstructionContext, clang::CXXBindTemporaryExpr const*, clang::MaterializeTemporaryExpr const*, clang::CXXConstructExpr const*, clang::ConstructionContext const*>(clang::BumpVectorContext&, clang::CXXBindTemporaryExpr const*, clang::MaterializeTemporaryExpr const*, clang::CXXConstructExpr const*, clang::ConstructionContext const*)
Line
Count
Source
130
562
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
562
    auto *CC = C.getAllocator().Allocate<T>();
132
562
    return new (CC) T(Args...);
133
562
  }
clang::CXX17ElidedCopyReturnedValueConstructionContext* clang::ConstructionContext::create<clang::CXX17ElidedCopyReturnedValueConstructionContext, clang::ReturnStmt const*, clang::CXXBindTemporaryExpr const*>(clang::BumpVectorContext&, clang::ReturnStmt const*, clang::CXXBindTemporaryExpr const*)
Line
Count
Source
130
52
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
52
    auto *CC = C.getAllocator().Allocate<T>();
132
52
    return new (CC) T(Args...);
133
52
  }
clang::CXX17ElidedCopyVariableConstructionContext* clang::ConstructionContext::create<clang::CXX17ElidedCopyVariableConstructionContext, clang::DeclStmt const*, clang::CXXBindTemporaryExpr const*>(clang::BumpVectorContext&, clang::DeclStmt const*, clang::CXXBindTemporaryExpr const*)
Line
Count
Source
130
56
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
56
    auto *CC = C.getAllocator().Allocate<T>();
132
56
    return new (CC) T(Args...);
133
56
  }
clang::SimpleTemporaryObjectConstructionContext* clang::ConstructionContext::create<clang::SimpleTemporaryObjectConstructionContext, clang::CXXBindTemporaryExpr const*, std::nullptr_t>(clang::BumpVectorContext&, clang::CXXBindTemporaryExpr const*, std::nullptr_t)
Line
Count
Source
130
342
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
342
    auto *CC = C.getAllocator().Allocate<T>();
132
342
    return new (CC) T(Args...);
133
342
  }
clang::SimpleTemporaryObjectConstructionContext* clang::ConstructionContext::create<clang::SimpleTemporaryObjectConstructionContext, std::nullptr_t, clang::MaterializeTemporaryExpr const*>(clang::BumpVectorContext&, std::nullptr_t, clang::MaterializeTemporaryExpr const*)
Line
Count
Source
130
811
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
811
    auto *CC = C.getAllocator().Allocate<T>();
132
811
    return new (CC) T(Args...);
133
811
  }
clang::ElidedTemporaryObjectConstructionContext* clang::ConstructionContext::create<clang::ElidedTemporaryObjectConstructionContext, std::nullptr_t, clang::MaterializeTemporaryExpr const*, clang::CXXConstructExpr const*, clang::ConstructionContext const*>(clang::BumpVectorContext&, std::nullptr_t, clang::MaterializeTemporaryExpr const*, clang::CXXConstructExpr const*, clang::ConstructionContext const*)
Line
Count
Source
130
326
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
326
    auto *CC = C.getAllocator().Allocate<T>();
132
326
    return new (CC) T(Args...);
133
326
  }
clang::SimpleReturnedValueConstructionContext* clang::ConstructionContext::create<clang::SimpleReturnedValueConstructionContext, clang::ReturnStmt const*>(clang::BumpVectorContext&, clang::ReturnStmt const*)
Line
Count
Source
130
622
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
622
    auto *CC = C.getAllocator().Allocate<T>();
132
622
    return new (CC) T(Args...);
133
622
  }
clang::SimpleConstructorInitializerConstructionContext* clang::ConstructionContext::create<clang::SimpleConstructorInitializerConstructionContext, clang::CXXCtorInitializer const*>(clang::BumpVectorContext&, clang::CXXCtorInitializer const*)
Line
Count
Source
130
1.33k
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
131
1.33k
    auto *CC = C.getAllocator().Allocate<T>();
132
1.33k
    return new (CC) T(Args...);
133
1.33k
  }
134
135
public:
136
  /// Consume the construction context layer, together with its parent layers,
137
  /// and wrap it up into a complete construction context. May return null
138
  /// if layers do not form any supported construction context.
139
  static const ConstructionContext *
140
  createFromLayers(BumpVectorContext &C,
141
                   const ConstructionContextLayer *TopLayer);
142
143
9.79k
  Kind getKind() const { return K; }
144
};
145
146
/// An abstract base class for local variable constructors.
147
class VariableConstructionContext : public ConstructionContext {
148
  const DeclStmt *DS;
149
150
protected:
151
  VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
152
4.09k
      : ConstructionContext(K), DS(DS) {
153
4.09k
    assert(classof(this));
154
4.09k
    assert(DS);
155
4.09k
  }
156
157
public:
158
4.66k
  const DeclStmt *getDeclStmt() const { return DS; }
159
160
  static bool classof(const ConstructionContext *CC) {
161
    return CC->getKind() >= VARIABLE_BEGIN &&
162
           CC->getKind() <= VARIABLE_END;
163
  }
164
};
165
166
/// Represents construction into a simple local variable, eg. T var(123);.
167
/// If a variable has an initializer, eg. T var = makeT();, then the final
168
/// elidable copy-constructor from makeT() into var would also be a simple
169
/// variable constructor handled by this class.
170
class SimpleVariableConstructionContext : public VariableConstructionContext {
171
  friend class ConstructionContext; // Allows to create<>() itself.
172
173
  explicit SimpleVariableConstructionContext(const DeclStmt *DS)
174
      : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
175
4.04k
                                    DS) {}
176
177
public:
178
  static bool classof(const ConstructionContext *CC) {
179
    return CC->getKind() == SimpleVariableKind;
180
  }
181
};
182
183
/// Represents construction into a simple variable with an initializer syntax,
184
/// with a single constructor, eg. T var = makeT();. Such construction context
185
/// may only appear in C++17 because previously it was split into a temporary
186
/// object constructor and an elidable simple variable copy-constructor and
187
/// we were producing separate construction contexts for these constructors.
188
/// In C++17 we have a single construction context that combines both.
189
/// Note that if the object has trivial destructor, then this code is
190
/// indistinguishable from a simple variable constructor on the AST level;
191
/// in this case we provide a simple variable construction context.
192
class CXX17ElidedCopyVariableConstructionContext
193
    : public VariableConstructionContext {
194
  const CXXBindTemporaryExpr *BTE;
195
196
  friend class ConstructionContext; // Allows to create<>() itself.
197
198
  explicit CXX17ElidedCopyVariableConstructionContext(
199
      const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
200
56
      : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
201
56
    assert(BTE);
202
56
  }
203
204
public:
205
2
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
206
207
  static bool classof(const ConstructionContext *CC) {
208
    return CC->getKind() == CXX17ElidedCopyVariableKind;
209
  }
210
};
211
212
// An abstract base class for constructor-initializer-based constructors.
213
class ConstructorInitializerConstructionContext : public ConstructionContext {
214
  const CXXCtorInitializer *I;
215
216
protected:
217
  explicit ConstructorInitializerConstructionContext(
218
      ConstructionContext::Kind K, const CXXCtorInitializer *I)
219
1.34k
      : ConstructionContext(K), I(I) {
220
1.34k
    assert(classof(this));
221
1.34k
    assert(I);
222
1.34k
  }
223
224
public:
225
827
  const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
226
227
  static bool classof(const ConstructionContext *CC) {
228
    return CC->getKind() >= INITIALIZER_BEGIN &&
229
           CC->getKind() <= INITIALIZER_END;
230
  }
231
};
232
233
/// Represents construction into a field or a base class within a bigger object
234
/// via a constructor initializer, eg. T(): field(123) { ... }.
235
class SimpleConstructorInitializerConstructionContext
236
    : public ConstructorInitializerConstructionContext {
237
  friend class ConstructionContext; // Allows to create<>() itself.
238
239
  explicit SimpleConstructorInitializerConstructionContext(
240
      const CXXCtorInitializer *I)
241
      : ConstructorInitializerConstructionContext(
242
1.33k
            ConstructionContext::SimpleConstructorInitializerKind, I) {}
243
244
public:
245
  static bool classof(const ConstructionContext *CC) {
246
    return CC->getKind() == SimpleConstructorInitializerKind;
247
  }
248
};
249
250
/// Represents construction into a field or a base class within a bigger object
251
/// via a constructor initializer, with a single constructor, eg.
252
/// T(): field(Field(123)) { ... }. Such construction context may only appear
253
/// in C++17 because previously it was split into a temporary object constructor
254
/// and an elidable simple constructor-initializer copy-constructor and we were
255
/// producing separate construction contexts for these constructors. In C++17
256
/// we have a single construction context that combines both. Note that if the
257
/// object has trivial destructor, then this code is indistinguishable from
258
/// a simple constructor-initializer constructor on the AST level; in this case
259
/// we provide a simple constructor-initializer construction context.
260
class CXX17ElidedCopyConstructorInitializerConstructionContext
261
    : public ConstructorInitializerConstructionContext {
262
  const CXXBindTemporaryExpr *BTE;
263
264
  friend class ConstructionContext; // Allows to create<>() itself.
265
266
  explicit CXX17ElidedCopyConstructorInitializerConstructionContext(
267
      const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
268
      : ConstructorInitializerConstructionContext(
269
            CXX17ElidedCopyConstructorInitializerKind, I),
270
12
        BTE(BTE) {
271
12
    assert(BTE);
272
12
  }
273
274
public:
275
2
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
276
277
  static bool classof(const ConstructionContext *CC) {
278
    return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
279
  }
280
};
281
282
/// Represents immediate initialization of memory allocated by operator new,
283
/// eg. new T(123);.
284
class NewAllocatedObjectConstructionContext : public ConstructionContext {
285
  const CXXNewExpr *NE;
286
287
  friend class ConstructionContext; // Allows to create<>() itself.
288
289
  explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE)
290
      : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
291
685
        NE(NE) {
292
685
    assert(NE);
293
685
  }
294
295
public:
296
478
  const CXXNewExpr *getCXXNewExpr() const { return NE; }
297
298
3.65k
  static bool classof(const ConstructionContext *CC) {
299
3.65k
    return CC->getKind() == NewAllocatedObjectKind;
300
3.65k
  }
301
};
302
303
/// Represents a temporary object, eg. T(123), that does not immediately cross
304
/// function boundaries "by value"; constructors that construct function
305
/// value-type arguments or values that are immediately returned from the
306
/// function that returns a value receive separate construction context kinds.
307
class TemporaryObjectConstructionContext : public ConstructionContext {
308
  const CXXBindTemporaryExpr *BTE;
309
  const MaterializeTemporaryExpr *MTE;
310
311
protected:
312
  explicit TemporaryObjectConstructionContext(
313
      ConstructionContext::Kind K, const CXXBindTemporaryExpr *BTE,
314
      const MaterializeTemporaryExpr *MTE)
315
2.91k
      : ConstructionContext(K), BTE(BTE), MTE(MTE) {
316
2.91k
    // Both BTE and MTE can be null here, all combinations possible.
317
2.91k
    // Even though for now at least one should be non-null, we simply haven't
318
2.91k
    // implemented the other case yet (this would be a temporary in the middle
319
2.91k
    // of nowhere that doesn't have a non-trivial destructor).
320
2.91k
  }
321
322
public:
323
  /// CXXBindTemporaryExpr here is non-null as long as the temporary has
324
  /// a non-trivial destructor.
325
2.00k
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const {
326
2.00k
    return BTE;
327
2.00k
  }
328
329
  /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
330
  /// used after construction, eg. by binding to a reference (lifetime
331
  /// extension), accessing a field, calling a method, or passing it into
332
  /// a function (an elidable copy or move constructor would be a common
333
  /// example) by reference.
334
2.00k
  const MaterializeTemporaryExpr *getMaterializedTemporaryExpr() const {
335
2.00k
    return MTE;
336
2.00k
  }
337
338
  static bool classof(const ConstructionContext *CC) {
339
    return CC->getKind() >= TEMPORARY_BEGIN && CC->getKind() <= TEMPORARY_END;
340
  }
341
};
342
343
/// Represents a temporary object that is not constructed for the purpose of
344
/// being immediately copied/moved by an elidable copy/move-constructor.
345
/// This includes temporary objects "in the middle of nowhere" like T(123) and
346
/// lifetime-extended temporaries.
347
class SimpleTemporaryObjectConstructionContext
348
    : public TemporaryObjectConstructionContext {
349
  friend class ConstructionContext; // Allows to create<>() itself.
350
351
  explicit SimpleTemporaryObjectConstructionContext(
352
      const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
353
      : TemporaryObjectConstructionContext(
354
2.03k
            ConstructionContext::SimpleTemporaryObjectKind, BTE, MTE) {}
355
356
public:
357
  static bool classof(const ConstructionContext *CC) {
358
    return CC->getKind() == SimpleTemporaryObjectKind;
359
  }
360
};
361
362
/// Represents a temporary object that is constructed for the sole purpose
363
/// of being immediately copied by an elidable copy/move constructor.
364
/// For example, T t = T(123); includes a temporary T(123) that is immediately
365
/// copied to variable t. In such cases the elidable copy can (but not
366
/// necessarily should) be omitted ("elided") accodring to the rules of the
367
/// language; the constructor would then construct variable t directly.
368
/// This construction context contains information of the elidable constructor
369
/// and its respective construction context.
370
class ElidedTemporaryObjectConstructionContext
371
    : public TemporaryObjectConstructionContext {
372
  const CXXConstructExpr *ElidedCE;
373
  const ConstructionContext *ElidedCC;
374
375
  friend class ConstructionContext; // Allows to create<>() itself.
376
377
  explicit ElidedTemporaryObjectConstructionContext(
378
      const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE,
379
      const CXXConstructExpr *ElidedCE, const ConstructionContext *ElidedCC)
380
      : TemporaryObjectConstructionContext(
381
            ConstructionContext::ElidedTemporaryObjectKind, BTE, MTE),
382
888
        ElidedCE(ElidedCE), ElidedCC(ElidedCC) {
383
888
    // Elided constructor and its context should be either both specified
384
888
    // or both unspecified. In the former case, the constructor must be
385
888
    // elidable.
386
888
    assert(ElidedCE && ElidedCE->isElidable() && ElidedCC);
387
888
  }
388
389
public:
390
812
  const CXXConstructExpr *getConstructorAfterElision() const {
391
812
    return ElidedCE;
392
812
  }
393
394
750
  const ConstructionContext *getConstructionContextAfterElision() const {
395
750
    return ElidedCC;
396
750
  }
397
398
  static bool classof(const ConstructionContext *CC) {
399
    return CC->getKind() == ElidedTemporaryObjectKind;
400
  }
401
};
402
403
class ReturnedValueConstructionContext : public ConstructionContext {
404
  const ReturnStmt *RS;
405
406
protected:
407
  explicit ReturnedValueConstructionContext(ConstructionContext::Kind K,
408
                                            const ReturnStmt *RS)
409
674
      : ConstructionContext(K), RS(RS) {
410
674
    assert(classof(this));
411
674
    assert(RS);
412
674
  }
413
414
public:
415
40
  const ReturnStmt *getReturnStmt() const { return RS; }
416
417
  static bool classof(const ConstructionContext *CC) {
418
    return CC->getKind() >= RETURNED_VALUE_BEGIN &&
419
           CC->getKind() <= RETURNED_VALUE_END;
420
  }
421
};
422
423
/// Represents a temporary object that is being immediately returned from a
424
/// function by value, eg. return t; or return T(123);. In this case there is
425
/// always going to be a constructor at the return site. However, the usual
426
/// temporary-related bureaucracy (CXXBindTemporaryExpr,
427
/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
428
class SimpleReturnedValueConstructionContext
429
    : public ReturnedValueConstructionContext {
430
  friend class ConstructionContext; // Allows to create<>() itself.
431
432
  explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS)
433
      : ReturnedValueConstructionContext(
434
622
            ConstructionContext::SimpleReturnedValueKind, RS) {}
435
436
public:
437
  static bool classof(const ConstructionContext *CC) {
438
    return CC->getKind() == SimpleReturnedValueKind;
439
  }
440
};
441
442
/// Represents a temporary object that is being immediately returned from a
443
/// function by value, eg. return t; or return T(123); in C++17.
444
/// In C++17 there is not going to be an elidable copy constructor at the
445
/// return site.  However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
446
/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
447
/// Note that if the object has trivial destructor, then this code is
448
/// indistinguishable from a simple returned value constructor on the AST level;
449
/// in this case we provide a simple returned value construction context.
450
class CXX17ElidedCopyReturnedValueConstructionContext
451
    : public ReturnedValueConstructionContext {
452
  const CXXBindTemporaryExpr *BTE;
453
454
  friend class ConstructionContext; // Allows to create<>() itself.
455
456
  explicit CXX17ElidedCopyReturnedValueConstructionContext(
457
      const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
458
      : ReturnedValueConstructionContext(
459
            ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
460
52
        BTE(BTE) {
461
52
    assert(BTE);
462
52
  }
463
464
public:
465
2
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
466
467
  static bool classof(const ConstructionContext *CC) {
468
    return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
469
  }
470
};
471
472
} // end namespace clang
473
474
#endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H