]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/ConstructionContext.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Analysis / ConstructionContext.h
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 #include "clang/AST/ExprObjC.h"
23
24 namespace clang {
25
26 /// Represents a single point (AST node) in the program that requires attention
27 /// during construction of an object. ConstructionContext would be represented
28 /// as a list of such items.
29 class ConstructionContextItem {
30 public:
31   enum ItemKind {
32     VariableKind,
33     NewAllocatorKind,
34     ReturnKind,
35     MaterializationKind,
36     TemporaryDestructorKind,
37     ElidedDestructorKind,
38     ElidableConstructorKind,
39     ArgumentKind,
40     STATEMENT_WITH_INDEX_KIND_BEGIN=ArgumentKind,
41     STATEMENT_WITH_INDEX_KIND_END=ArgumentKind,
42     STATEMENT_KIND_BEGIN = VariableKind,
43     STATEMENT_KIND_END = ArgumentKind,
44     InitializerKind,
45     INITIALIZER_KIND_BEGIN=InitializerKind,
46     INITIALIZER_KIND_END=InitializerKind
47   };
48
49   LLVM_DUMP_METHOD static StringRef getKindAsString(ItemKind K) {
50     switch (K) {
51       case VariableKind:            return "construct into local variable";
52       case NewAllocatorKind:        return "construct into new-allocator";
53       case ReturnKind:              return "construct into return address";
54       case MaterializationKind:     return "materialize temporary";
55       case TemporaryDestructorKind: return "destroy temporary";
56       case ElidedDestructorKind:    return "elide destructor";
57       case ElidableConstructorKind: return "elide constructor";
58       case ArgumentKind:            return "construct into argument";
59       case InitializerKind:         return "construct into member variable";
60     };
61     llvm_unreachable("Unknown ItemKind");
62   }
63
64 private:
65   const void *const Data;
66   const ItemKind Kind;
67   const unsigned Index = 0;
68
69   bool hasStatement() const {
70     return Kind >= STATEMENT_KIND_BEGIN &&
71            Kind <= STATEMENT_KIND_END;
72   }
73
74   bool hasIndex() const {
75     return Kind >= STATEMENT_WITH_INDEX_KIND_BEGIN &&
76            Kind >= STATEMENT_WITH_INDEX_KIND_END;
77   }
78
79   bool hasInitializer() const {
80     return Kind >= INITIALIZER_KIND_BEGIN &&
81            Kind <= INITIALIZER_KIND_END;
82   }
83
84 public:
85   // ConstructionContextItem should be simple enough so that it was easy to
86   // re-construct it from the AST node it captures. For that reason we provide
87   // simple implicit conversions from all sorts of supported AST nodes.
88   ConstructionContextItem(const DeclStmt *DS)
89       : Data(DS), Kind(VariableKind) {}
90
91   ConstructionContextItem(const CXXNewExpr *NE)
92       : Data(NE), Kind(NewAllocatorKind) {}
93
94   ConstructionContextItem(const ReturnStmt *RS)
95       : Data(RS), Kind(ReturnKind) {}
96
97   ConstructionContextItem(const MaterializeTemporaryExpr *MTE)
98       : Data(MTE), Kind(MaterializationKind) {}
99
100   ConstructionContextItem(const CXXBindTemporaryExpr *BTE,
101                           bool IsElided = false)
102       : Data(BTE),
103         Kind(IsElided ? ElidedDestructorKind : TemporaryDestructorKind) {}
104
105   ConstructionContextItem(const CXXConstructExpr *CE)
106       : Data(CE), Kind(ElidableConstructorKind) {}
107
108   ConstructionContextItem(const CallExpr *CE, unsigned Index)
109       : Data(CE), Kind(ArgumentKind), Index(Index) {}
110
111   ConstructionContextItem(const CXXConstructExpr *CE, unsigned Index)
112       : Data(CE), Kind(ArgumentKind), Index(Index) {}
113
114   ConstructionContextItem(const ObjCMessageExpr *ME, unsigned Index)
115       : Data(ME), Kind(ArgumentKind), Index(Index) {}
116
117   // A polymorphic version of the previous calls with dynamic type check.
118   ConstructionContextItem(const Expr *E, unsigned Index)
119       : Data(E), Kind(ArgumentKind), Index(Index) {
120     assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
121            isa<ObjCMessageExpr>(E));
122   }
123
124   ConstructionContextItem(const CXXCtorInitializer *Init)
125       : Data(Init), Kind(InitializerKind), Index(0) {}
126
127   ItemKind getKind() const { return Kind; }
128
129   LLVM_DUMP_METHOD StringRef getKindAsString() const {
130     return getKindAsString(getKind());
131   }
132
133   /// The construction site - the statement that triggered the construction
134   /// for one of its parts. For instance, stack variable declaration statement
135   /// triggers construction of itself or its elements if it's an array,
136   /// new-expression triggers construction of the newly allocated object(s).
137   const Stmt *getStmt() const {
138     assert(hasStatement());
139     return static_cast<const Stmt *>(Data);
140   }
141
142   const Stmt *getStmtOrNull() const {
143     return hasStatement() ? getStmt() : nullptr;
144   }
145
146   /// The construction site is not necessarily a statement. It may also be a
147   /// CXXCtorInitializer, which means that a member variable is being
148   /// constructed during initialization of the object that contains it.
149   const CXXCtorInitializer *getCXXCtorInitializer() const {
150     assert(hasInitializer());
151     return static_cast<const CXXCtorInitializer *>(Data);
152   }
153
154   /// If a single trigger statement triggers multiple constructors, they are
155   /// usually being enumerated. This covers function argument constructors
156   /// triggered by a call-expression and items in an initializer list triggered
157   /// by an init-list-expression.
158   unsigned getIndex() const {
159     // This is a fairly specific request. Let's make sure the user knows
160     // what he's doing.
161     assert(hasIndex());
162     return Index;
163   }
164
165   void Profile(llvm::FoldingSetNodeID &ID) const {
166     ID.AddPointer(Data);
167     ID.AddInteger(Kind);
168     ID.AddInteger(Index);
169   }
170
171   bool operator==(const ConstructionContextItem &Other) const {
172     // For most kinds the Index comparison is trivially true, but
173     // checking kind separately doesn't seem to be less expensive
174     // than checking Index. Same in operator<().
175     return std::make_tuple(Data, Kind, Index) ==
176            std::make_tuple(Other.Data, Other.Kind, Other.Index);
177   }
178
179   bool operator<(const ConstructionContextItem &Other) const {
180     return std::make_tuple(Data, Kind, Index) <
181            std::make_tuple(Other.Data, Other.Kind, Other.Index);
182   }
183 };
184
185 /// Construction context can be seen as a linked list of multiple layers.
186 /// Sometimes a single trigger is not enough to describe the construction
187 /// site. That's what causing us to have a chain of "partial" construction
188 /// context layers. Some examples:
189 /// - A constructor within in an aggregate initializer list within a variable
190 ///   would have a construction context of the initializer list with
191 ///   the parent construction context of a variable.
192 /// - A constructor for a temporary that needs to be both destroyed
193 ///   and materialized into an elidable copy constructor would have a
194 ///   construction context of a CXXBindTemporaryExpr with the parent
195 ///   construction context of a MaterializeTemproraryExpr.
196 /// Not all of these are currently supported.
197 /// Layers are created gradually while traversing the AST, and layers that
198 /// represent the outmost AST nodes are built first, while the node that
199 /// immediately contains the constructor would be built last and capture the
200 /// previous layers as its parents. Construction context captures the last layer
201 /// (which has links to the previous layers) and classifies the seemingly
202 /// arbitrary chain of layers into one of the possible ways of constructing
203 /// an object in C++ for user-friendly experience.
204 class ConstructionContextLayer {
205   const ConstructionContextLayer *Parent = nullptr;
206   ConstructionContextItem Item;
207
208   ConstructionContextLayer(ConstructionContextItem Item,
209                            const ConstructionContextLayer *Parent)
210       : Parent(Parent), Item(Item) {}
211
212 public:
213   static const ConstructionContextLayer *
214   create(BumpVectorContext &C, const ConstructionContextItem &Item,
215          const ConstructionContextLayer *Parent = nullptr);
216
217   const ConstructionContextItem &getItem() const { return Item; }
218   const ConstructionContextLayer *getParent() const { return Parent; }
219   bool isLast() const { return !Parent; }
220
221   /// See if Other is a proper initial segment of this construction context
222   /// in terms of the parent chain - i.e. a few first parents coincide and
223   /// then the other context terminates but our context goes further - i.e.,
224   /// we are providing the same context that the other context provides,
225   /// and a bit more above that.
226   bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const;
227 };
228
229
230 /// ConstructionContext's subclasses describe different ways of constructing
231 /// an object in C++. The context re-captures the essential parent AST nodes
232 /// of the CXXConstructExpr it is assigned to and presents these nodes
233 /// through easy-to-understand accessor methods.
234 class ConstructionContext {
235 public:
236   enum Kind {
237     SimpleVariableKind,
238     CXX17ElidedCopyVariableKind,
239     VARIABLE_BEGIN = SimpleVariableKind,
240     VARIABLE_END = CXX17ElidedCopyVariableKind,
241     SimpleConstructorInitializerKind,
242     CXX17ElidedCopyConstructorInitializerKind,
243     INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
244     INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
245     NewAllocatedObjectKind,
246     SimpleTemporaryObjectKind,
247     ElidedTemporaryObjectKind,
248     TEMPORARY_BEGIN = SimpleTemporaryObjectKind,
249     TEMPORARY_END = ElidedTemporaryObjectKind,
250     SimpleReturnedValueKind,
251     CXX17ElidedCopyReturnedValueKind,
252     RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
253     RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind,
254     ArgumentKind
255   };
256
257 protected:
258   Kind K;
259
260   // Do not make public! These need to only be constructed
261   // via createFromLayers().
262   explicit ConstructionContext(Kind K) : K(K) {}
263
264 private:
265   // A helper function for constructing an instance into a bump vector context.
266   template <typename T, typename... ArgTypes>
267   static T *create(BumpVectorContext &C, ArgTypes... Args) {
268     auto *CC = C.getAllocator().Allocate<T>();
269     return new (CC) T(Args...);
270   }
271
272   // A sub-routine of createFromLayers() that deals with temporary objects
273   // that need to be materialized. The BTE argument is for the situation when
274   // the object also needs to be bound for destruction.
275   static const ConstructionContext *createMaterializedTemporaryFromLayers(
276       BumpVectorContext &C, const MaterializeTemporaryExpr *MTE,
277       const CXXBindTemporaryExpr *BTE,
278       const ConstructionContextLayer *ParentLayer);
279
280   // A sub-routine of createFromLayers() that deals with temporary objects
281   // that need to be bound for destruction. Automatically finds out if the
282   // object also needs to be materialized and delegates to
283   // createMaterializedTemporaryFromLayers() if necessary.
284   static const ConstructionContext *
285   createBoundTemporaryFromLayers(
286       BumpVectorContext &C, const CXXBindTemporaryExpr *BTE,
287       const ConstructionContextLayer *ParentLayer);
288
289 public:
290   /// Consume the construction context layer, together with its parent layers,
291   /// and wrap it up into a complete construction context. May return null
292   /// if layers do not form any supported construction context.
293   static const ConstructionContext *
294   createFromLayers(BumpVectorContext &C,
295                    const ConstructionContextLayer *TopLayer);
296
297   Kind getKind() const { return K; }
298 };
299
300 /// An abstract base class for local variable constructors.
301 class VariableConstructionContext : public ConstructionContext {
302   const DeclStmt *DS;
303
304 protected:
305   VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
306       : ConstructionContext(K), DS(DS) {
307     assert(classof(this));
308     assert(DS);
309   }
310
311 public:
312   const DeclStmt *getDeclStmt() const { return DS; }
313
314   static bool classof(const ConstructionContext *CC) {
315     return CC->getKind() >= VARIABLE_BEGIN &&
316            CC->getKind() <= VARIABLE_END;
317   }
318 };
319
320 /// Represents construction into a simple local variable, eg. T var(123);.
321 /// If a variable has an initializer, eg. T var = makeT();, then the final
322 /// elidable copy-constructor from makeT() into var would also be a simple
323 /// variable constructor handled by this class.
324 class SimpleVariableConstructionContext : public VariableConstructionContext {
325   friend class ConstructionContext; // Allows to create<>() itself.
326
327   explicit SimpleVariableConstructionContext(const DeclStmt *DS)
328       : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
329                                     DS) {}
330
331 public:
332   static bool classof(const ConstructionContext *CC) {
333     return CC->getKind() == SimpleVariableKind;
334   }
335 };
336
337 /// Represents construction into a simple variable with an initializer syntax,
338 /// with a single constructor, eg. T var = makeT();. Such construction context
339 /// may only appear in C++17 because previously it was split into a temporary
340 /// object constructor and an elidable simple variable copy-constructor and
341 /// we were producing separate construction contexts for these constructors.
342 /// In C++17 we have a single construction context that combines both.
343 /// Note that if the object has trivial destructor, then this code is
344 /// indistinguishable from a simple variable constructor on the AST level;
345 /// in this case we provide a simple variable construction context.
346 class CXX17ElidedCopyVariableConstructionContext
347     : public VariableConstructionContext {
348   const CXXBindTemporaryExpr *BTE;
349
350   friend class ConstructionContext; // Allows to create<>() itself.
351
352   explicit CXX17ElidedCopyVariableConstructionContext(
353       const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
354       : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
355     assert(BTE);
356   }
357
358 public:
359   const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
360
361   static bool classof(const ConstructionContext *CC) {
362     return CC->getKind() == CXX17ElidedCopyVariableKind;
363   }
364 };
365
366 // An abstract base class for constructor-initializer-based constructors.
367 class ConstructorInitializerConstructionContext : public ConstructionContext {
368   const CXXCtorInitializer *I;
369
370 protected:
371   explicit ConstructorInitializerConstructionContext(
372       ConstructionContext::Kind K, const CXXCtorInitializer *I)
373       : ConstructionContext(K), I(I) {
374     assert(classof(this));
375     assert(I);
376   }
377
378 public:
379   const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
380
381   static bool classof(const ConstructionContext *CC) {
382     return CC->getKind() >= INITIALIZER_BEGIN &&
383            CC->getKind() <= INITIALIZER_END;
384   }
385 };
386
387 /// Represents construction into a field or a base class within a bigger object
388 /// via a constructor initializer, eg. T(): field(123) { ... }.
389 class SimpleConstructorInitializerConstructionContext
390     : public ConstructorInitializerConstructionContext {
391   friend class ConstructionContext; // Allows to create<>() itself.
392
393   explicit SimpleConstructorInitializerConstructionContext(
394       const CXXCtorInitializer *I)
395       : ConstructorInitializerConstructionContext(
396             ConstructionContext::SimpleConstructorInitializerKind, I) {}
397
398 public:
399   static bool classof(const ConstructionContext *CC) {
400     return CC->getKind() == SimpleConstructorInitializerKind;
401   }
402 };
403
404 /// Represents construction into a field or a base class within a bigger object
405 /// via a constructor initializer, with a single constructor, eg.
406 /// T(): field(Field(123)) { ... }. Such construction context may only appear
407 /// in C++17 because previously it was split into a temporary object constructor
408 /// and an elidable simple constructor-initializer copy-constructor and we were
409 /// producing separate construction contexts for these constructors. In C++17
410 /// we have a single construction context that combines both. Note that if the
411 /// object has trivial destructor, then this code is indistinguishable from
412 /// a simple constructor-initializer constructor on the AST level; in this case
413 /// we provide a simple constructor-initializer construction context.
414 class CXX17ElidedCopyConstructorInitializerConstructionContext
415     : public ConstructorInitializerConstructionContext {
416   const CXXBindTemporaryExpr *BTE;
417
418   friend class ConstructionContext; // Allows to create<>() itself.
419
420   explicit CXX17ElidedCopyConstructorInitializerConstructionContext(
421       const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
422       : ConstructorInitializerConstructionContext(
423             CXX17ElidedCopyConstructorInitializerKind, I),
424         BTE(BTE) {
425     assert(BTE);
426   }
427
428 public:
429   const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
430
431   static bool classof(const ConstructionContext *CC) {
432     return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
433   }
434 };
435
436 /// Represents immediate initialization of memory allocated by operator new,
437 /// eg. new T(123);.
438 class NewAllocatedObjectConstructionContext : public ConstructionContext {
439   const CXXNewExpr *NE;
440
441   friend class ConstructionContext; // Allows to create<>() itself.
442
443   explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE)
444       : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
445         NE(NE) {
446     assert(NE);
447   }
448
449 public:
450   const CXXNewExpr *getCXXNewExpr() const { return NE; }
451
452   static bool classof(const ConstructionContext *CC) {
453     return CC->getKind() == NewAllocatedObjectKind;
454   }
455 };
456
457 /// Represents a temporary object, eg. T(123), that does not immediately cross
458 /// function boundaries "by value"; constructors that construct function
459 /// value-type arguments or values that are immediately returned from the
460 /// function that returns a value receive separate construction context kinds.
461 class TemporaryObjectConstructionContext : public ConstructionContext {
462   const CXXBindTemporaryExpr *BTE;
463   const MaterializeTemporaryExpr *MTE;
464
465 protected:
466   explicit TemporaryObjectConstructionContext(
467       ConstructionContext::Kind K, const CXXBindTemporaryExpr *BTE,
468       const MaterializeTemporaryExpr *MTE)
469       : ConstructionContext(K), BTE(BTE), MTE(MTE) {
470     // Both BTE and MTE can be null here, all combinations possible.
471     // Even though for now at least one should be non-null, we simply haven't
472     // implemented the other case yet (this would be a temporary in the middle
473     // of nowhere that doesn't have a non-trivial destructor).
474   }
475
476 public:
477   /// CXXBindTemporaryExpr here is non-null as long as the temporary has
478   /// a non-trivial destructor.
479   const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const {
480     return BTE;
481   }
482
483   /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
484   /// used after construction, eg. by binding to a reference (lifetime
485   /// extension), accessing a field, calling a method, or passing it into
486   /// a function (an elidable copy or move constructor would be a common
487   /// example) by reference.
488   const MaterializeTemporaryExpr *getMaterializedTemporaryExpr() const {
489     return MTE;
490   }
491
492   static bool classof(const ConstructionContext *CC) {
493     return CC->getKind() >= TEMPORARY_BEGIN && CC->getKind() <= TEMPORARY_END;
494   }
495 };
496
497 /// Represents a temporary object that is not constructed for the purpose of
498 /// being immediately copied/moved by an elidable copy/move-constructor.
499 /// This includes temporary objects "in the middle of nowhere" like T(123) and
500 /// lifetime-extended temporaries.
501 class SimpleTemporaryObjectConstructionContext
502     : public TemporaryObjectConstructionContext {
503   friend class ConstructionContext; // Allows to create<>() itself.
504
505   explicit SimpleTemporaryObjectConstructionContext(
506       const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
507       : TemporaryObjectConstructionContext(
508             ConstructionContext::SimpleTemporaryObjectKind, BTE, MTE) {}
509
510 public:
511   static bool classof(const ConstructionContext *CC) {
512     return CC->getKind() == SimpleTemporaryObjectKind;
513   }
514 };
515
516 /// Represents a temporary object that is constructed for the sole purpose
517 /// of being immediately copied by an elidable copy/move constructor.
518 /// For example, T t = T(123); includes a temporary T(123) that is immediately
519 /// copied to variable t. In such cases the elidable copy can (but not
520 /// necessarily should) be omitted ("elided") accodring to the rules of the
521 /// language; the constructor would then construct variable t directly.
522 /// This construction context contains information of the elidable constructor
523 /// and its respective construction context.
524 class ElidedTemporaryObjectConstructionContext
525     : public TemporaryObjectConstructionContext {
526   const CXXConstructExpr *ElidedCE;
527   const ConstructionContext *ElidedCC;
528
529   friend class ConstructionContext; // Allows to create<>() itself.
530
531   explicit ElidedTemporaryObjectConstructionContext(
532       const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE,
533       const CXXConstructExpr *ElidedCE, const ConstructionContext *ElidedCC)
534       : TemporaryObjectConstructionContext(
535             ConstructionContext::ElidedTemporaryObjectKind, BTE, MTE),
536         ElidedCE(ElidedCE), ElidedCC(ElidedCC) {
537     // Elided constructor and its context should be either both specified
538     // or both unspecified. In the former case, the constructor must be
539     // elidable.
540     assert(ElidedCE && ElidedCE->isElidable() && ElidedCC);
541   }
542
543 public:
544   const CXXConstructExpr *getConstructorAfterElision() const {
545     return ElidedCE;
546   }
547
548   const ConstructionContext *getConstructionContextAfterElision() const {
549     return ElidedCC;
550   }
551
552   static bool classof(const ConstructionContext *CC) {
553     return CC->getKind() == ElidedTemporaryObjectKind;
554   }
555 };
556
557 class ReturnedValueConstructionContext : public ConstructionContext {
558   const ReturnStmt *RS;
559
560 protected:
561   explicit ReturnedValueConstructionContext(ConstructionContext::Kind K,
562                                             const ReturnStmt *RS)
563       : ConstructionContext(K), RS(RS) {
564     assert(classof(this));
565     assert(RS);
566   }
567
568 public:
569   const ReturnStmt *getReturnStmt() const { return RS; }
570
571   static bool classof(const ConstructionContext *CC) {
572     return CC->getKind() >= RETURNED_VALUE_BEGIN &&
573            CC->getKind() <= RETURNED_VALUE_END;
574   }
575 };
576
577 /// Represents a temporary object that is being immediately returned from a
578 /// function by value, eg. return t; or return T(123);. In this case there is
579 /// always going to be a constructor at the return site. However, the usual
580 /// temporary-related bureaucracy (CXXBindTemporaryExpr,
581 /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
582 class SimpleReturnedValueConstructionContext
583     : public ReturnedValueConstructionContext {
584   friend class ConstructionContext; // Allows to create<>() itself.
585
586   explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS)
587       : ReturnedValueConstructionContext(
588             ConstructionContext::SimpleReturnedValueKind, RS) {}
589
590 public:
591   static bool classof(const ConstructionContext *CC) {
592     return CC->getKind() == SimpleReturnedValueKind;
593   }
594 };
595
596 /// Represents a temporary object that is being immediately returned from a
597 /// function by value, eg. return t; or return T(123); in C++17.
598 /// In C++17 there is not going to be an elidable copy constructor at the
599 /// return site.  However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
600 /// MaterializeTemporaryExpr) is normally located in the caller function's AST.
601 /// Note that if the object has trivial destructor, then this code is
602 /// indistinguishable from a simple returned value constructor on the AST level;
603 /// in this case we provide a simple returned value construction context.
604 class CXX17ElidedCopyReturnedValueConstructionContext
605     : public ReturnedValueConstructionContext {
606   const CXXBindTemporaryExpr *BTE;
607
608   friend class ConstructionContext; // Allows to create<>() itself.
609
610   explicit CXX17ElidedCopyReturnedValueConstructionContext(
611       const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
612       : ReturnedValueConstructionContext(
613             ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
614         BTE(BTE) {
615     assert(BTE);
616   }
617
618 public:
619   const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
620
621   static bool classof(const ConstructionContext *CC) {
622     return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
623   }
624 };
625
626 class ArgumentConstructionContext : public ConstructionContext {
627   // The call of which the context is an argument.
628   const Expr *CE;
629
630   // Which argument we're constructing. Note that when numbering between
631   // arguments and parameters is inconsistent (eg., operator calls),
632   // this is the index of the argument, not of the parameter.
633   unsigned Index;
634
635   // Whether the object needs to be destroyed.
636   const CXXBindTemporaryExpr *BTE;
637
638   friend class ConstructionContext; // Allows to create<>() itself.
639
640   explicit ArgumentConstructionContext(const Expr *CE, unsigned Index,
641                                        const CXXBindTemporaryExpr *BTE)
642       : ConstructionContext(ArgumentKind), CE(CE),
643         Index(Index), BTE(BTE) {
644     assert(isa<CallExpr>(CE) || isa<CXXConstructExpr>(CE) ||
645            isa<ObjCMessageExpr>(CE));
646     // BTE is optional.
647   }
648
649 public:
650   const Expr *getCallLikeExpr() const { return CE; }
651   unsigned getIndex() const { return Index; }
652   const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }
653
654   static bool classof(const ConstructionContext *CC) {
655     return CC->getKind() == ArgumentKind;
656   }
657 };
658
659 } // end namespace clang
660
661 #endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H