Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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