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