//===- ConstructionContext.h - CFG constructor information ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the ConstructionContext class and its sub-classes,
// which represent various different ways of constructing C++ objects
// with the additional information the users may want to know about
// the constructor.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
#define LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H

#include "clang/Analysis/Support/BumpVector.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"

namespace clang {

/// Represents a single point (AST node) in the program that requires attention
/// during construction of an object. ConstructionContext would be represented
/// as a list of such items.
class ConstructionContextItem {
public:
  enum ItemKind {
    VariableKind,
    NewAllocatorKind,
    ReturnKind,
    MaterializationKind,
    TemporaryDestructorKind,
    ElidedDestructorKind,
    ElidableConstructorKind,
    ArgumentKind,
    STATEMENT_WITH_INDEX_KIND_BEGIN=ArgumentKind,
    STATEMENT_WITH_INDEX_KIND_END=ArgumentKind,
    STATEMENT_KIND_BEGIN = VariableKind,
    STATEMENT_KIND_END = ArgumentKind,
    InitializerKind,
    INITIALIZER_KIND_BEGIN=InitializerKind,
    INITIALIZER_KIND_END=InitializerKind
  };

  LLVM_DUMP_METHOD static StringRef getKindAsString(ItemKind K) {
    switch (K) {
      case VariableKind:            return "construct into local variable";
      case NewAllocatorKind:        return "construct into new-allocator";
      case ReturnKind:              return "construct into return address";
      case MaterializationKind:     return "materialize temporary";
      case TemporaryDestructorKind: return "destroy temporary";
      case ElidedDestructorKind:    return "elide destructor";
      case ElidableConstructorKind: return "elide constructor";
      case ArgumentKind:            return "construct into argument";
      case InitializerKind:         return "construct into member variable";
    };
    llvm_unreachable("Unknown ItemKind");
  }

private:
  const void *const Data;
  const ItemKind Kind;
  const unsigned Index = 0;

  bool hasStatement() const {
    return Kind >= STATEMENT_KIND_BEGIN &&
           Kind <= STATEMENT_KIND_END;
  }

  bool hasIndex() const {
    return Kind >= STATEMENT_WITH_INDEX_KIND_BEGIN &&
           Kind >= STATEMENT_WITH_INDEX_KIND_END;
  }

  bool hasInitializer() const {
    return Kind >= INITIALIZER_KIND_BEGIN &&
           Kind <= INITIALIZER_KIND_END;
  }

public:
  // ConstructionContextItem should be simple enough so that it was easy to
  // re-construct it from the AST node it captures. For that reason we provide
  // simple implicit conversions from all sorts of supported AST nodes.
  ConstructionContextItem(const DeclStmt *DS)
      : Data(DS), Kind(VariableKind) {}

  ConstructionContextItem(const CXXNewExpr *NE)
      : Data(NE), Kind(NewAllocatorKind) {}

  ConstructionContextItem(const ReturnStmt *RS)
      : Data(RS), Kind(ReturnKind) {}

  ConstructionContextItem(const MaterializeTemporaryExpr *MTE)
      : Data(MTE), Kind(MaterializationKind) {}

  ConstructionContextItem(const CXXBindTemporaryExpr *BTE,
                          bool IsElided = false)
      : Data(BTE),
        Kind(IsElided ? ElidedDestructorKind : TemporaryDestructorKind) {}

  ConstructionContextItem(const CXXConstructExpr *CE)
      : Data(CE), Kind(ElidableConstructorKind) {}

  ConstructionContextItem(const CallExpr *CE, unsigned Index)
      : Data(CE), Kind(ArgumentKind), Index(Index) {}

  ConstructionContextItem(const CXXConstructExpr *CE, unsigned Index)
      : Data(CE), Kind(ArgumentKind), Index(Index) {}

  ConstructionContextItem(const ObjCMessageExpr *ME, unsigned Index)
      : Data(ME), Kind(ArgumentKind), Index(Index) {}

  // A polymorphic version of the previous calls with dynamic type check.
  ConstructionContextItem(const Expr *E, unsigned Index)
      : Data(E), Kind(ArgumentKind), Index(Index) {
    assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
           isa<ObjCMessageExpr>(E));
  }

  ConstructionContextItem(const CXXCtorInitializer *Init)
      : Data(Init), Kind(InitializerKind), Index(0) {}

  ItemKind getKind() const { return Kind; }

  LLVM_DUMP_METHOD StringRef getKindAsString() const {
    return getKindAsString(getKind());
  }

  /// The construction site - the statement that triggered the construction
  /// for one of its parts. For instance, stack variable declaration statement
  /// triggers construction of itself or its elements if it's an array,
  /// new-expression triggers construction of the newly allocated object(s).
  const Stmt *getStmt() const {
    assert(hasStatement());
    return static_cast<const Stmt *>(Data);
  }

  const Stmt *getStmtOrNull() const {
    return hasStatement() ? getStmt() : nullptr;
  }

  /// The construction site is not necessarily a statement. It may also be a
  /// CXXCtorInitializer, which means that a member variable is being
  /// constructed during initialization of the object that contains it.
  const CXXCtorInitializer *getCXXCtorInitializer() const {
    assert(hasInitializer());
    return static_cast<const CXXCtorInitializer *>(Data);
  }

  /// If a single trigger statement triggers multiple constructors, they are
  /// usually being enumerated. This covers function argument constructors
  /// triggered by a call-expression and items in an initializer list triggered
  /// by an init-list-expression.
  unsigned getIndex() const {
    // This is a fairly specific request. Let's make sure the user knows
    // what he's doing.
    assert(hasIndex());
    return Index;
  }

  void Profile(llvm::FoldingSetNodeID &ID) const {
    ID.AddPointer(Data);
    ID.AddInteger(Kind);
    ID.AddInteger(Index);
  }

  bool operator==(const ConstructionContextItem &Other) const {
    // For most kinds the Index comparison is trivially true, but
    // checking kind separately doesn't seem to be less expensive
    // than checking Index. Same in operator<().
    return std::make_tuple(Data, Kind, Index) ==
           std::make_tuple(Other.Data, Other.Kind, Other.Index);
  }

  bool operator<(const ConstructionContextItem &Other) const {
    return std::make_tuple(Data, Kind, Index) <
           std::make_tuple(Other.Data, Other.Kind, Other.Index);
  }
};

/// Construction context can be seen as a linked list of multiple layers.
/// Sometimes a single trigger is not enough to describe the construction
/// site. That's what causing us to have a chain of "partial" construction
/// context layers. Some examples:
/// - A constructor within in an aggregate initializer list within a variable
///   would have a construction context of the initializer list with
///   the parent construction context of a variable.
/// - A constructor for a temporary that needs to be both destroyed
///   and materialized into an elidable copy constructor would have a
///   construction context of a CXXBindTemporaryExpr with the parent
///   construction context of a MaterializeTemproraryExpr.
/// Not all of these are currently supported.
/// Layers are created gradually while traversing the AST, and layers that
/// represent the outmost AST nodes are built first, while the node that
/// immediately contains the constructor would be built last and capture the
/// previous layers as its parents. Construction context captures the last layer
/// (which has links to the previous layers) and classifies the seemingly
/// arbitrary chain of layers into one of the possible ways of constructing
/// an object in C++ for user-friendly experience.
class ConstructionContextLayer {
  const ConstructionContextLayer *Parent = nullptr;
  ConstructionContextItem Item;

  ConstructionContextLayer(ConstructionContextItem Item,
                           const ConstructionContextLayer *Parent)
      : Parent(Parent), Item(Item) {}

public:
  static const ConstructionContextLayer *
  create(BumpVectorContext &C, const ConstructionContextItem &Item,
         const ConstructionContextLayer *Parent = nullptr);

  const ConstructionContextItem &getItem() const { return Item; }
  const ConstructionContextLayer *getParent() const { return Parent; }
  bool isLast() const { return !Parent; }

  /// See if Other is a proper initial segment of this construction context
  /// in terms of the parent chain - i.e. a few first parents coincide and
  /// then the other context terminates but our context goes further - i.e.,
  /// we are providing the same context that the other context provides,
  /// and a bit more above that.
  bool isStrictlyMoreSpecificThan(const ConstructionContextLayer *Other) const;
};


/// ConstructionContext's subclasses describe different ways of constructing
/// an object in C++. The context re-captures the essential parent AST nodes
/// of the CXXConstructExpr it is assigned to and presents these nodes
/// through easy-to-understand accessor methods.
class ConstructionContext {
public:
  enum Kind {
    SimpleVariableKind,
    CXX17ElidedCopyVariableKind,
    VARIABLE_BEGIN = SimpleVariableKind,
    VARIABLE_END = CXX17ElidedCopyVariableKind,
    SimpleConstructorInitializerKind,
    CXX17ElidedCopyConstructorInitializerKind,
    INITIALIZER_BEGIN = SimpleConstructorInitializerKind,
    INITIALIZER_END = CXX17ElidedCopyConstructorInitializerKind,
    NewAllocatedObjectKind,
    SimpleTemporaryObjectKind,
    ElidedTemporaryObjectKind,
    TEMPORARY_BEGIN = SimpleTemporaryObjectKind,
    TEMPORARY_END = ElidedTemporaryObjectKind,
    SimpleReturnedValueKind,
    CXX17ElidedCopyReturnedValueKind,
    RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
    RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind,
    ArgumentKind
  };

protected:
  Kind K;

  // Do not make public! These need to only be constructed
  // via createFromLayers().
  explicit ConstructionContext(Kind K) : K(K) {}

private:
  // A helper function for constructing an instance into a bump vector context.
  template <typename T, typename... ArgTypes>
  static T *create(BumpVectorContext &C, ArgTypes... Args) {
    auto *CC = C.getAllocator().Allocate<T>();
    return new (CC) T(Args...);
  }

  // A sub-routine of createFromLayers() that deals with temporary objects
  // that need to be materialized. The BTE argument is for the situation when
  // the object also needs to be bound for destruction.
  static const ConstructionContext *createMaterializedTemporaryFromLayers(
      BumpVectorContext &C, const MaterializeTemporaryExpr *MTE,
      const CXXBindTemporaryExpr *BTE,
      const ConstructionContextLayer *ParentLayer);

  // A sub-routine of createFromLayers() that deals with temporary objects
  // that need to be bound for destruction. Automatically finds out if the
  // object also needs to be materialized and delegates to
  // createMaterializedTemporaryFromLayers() if necessary.
  static const ConstructionContext *
  createBoundTemporaryFromLayers(
      BumpVectorContext &C, const CXXBindTemporaryExpr *BTE,
      const ConstructionContextLayer *ParentLayer);

public:
  /// Consume the construction context layer, together with its parent layers,
  /// and wrap it up into a complete construction context. May return null
  /// if layers do not form any supported construction context.
  static const ConstructionContext *
  createFromLayers(BumpVectorContext &C,
                   const ConstructionContextLayer *TopLayer);

  Kind getKind() const { return K; }
};

/// An abstract base class for local variable constructors.
class VariableConstructionContext : public ConstructionContext {
  const DeclStmt *DS;

protected:
  VariableConstructionContext(ConstructionContext::Kind K, const DeclStmt *DS)
      : ConstructionContext(K), DS(DS) {
    assert(classof(this));
    assert(DS);
  }

public:
  const DeclStmt *getDeclStmt() const { return DS; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() >= VARIABLE_BEGIN &&
           CC->getKind() <= VARIABLE_END;
  }
};

/// Represents construction into a simple local variable, eg. T var(123);.
/// If a variable has an initializer, eg. T var = makeT();, then the final
/// elidable copy-constructor from makeT() into var would also be a simple
/// variable constructor handled by this class.
class SimpleVariableConstructionContext : public VariableConstructionContext {
  friend class ConstructionContext; // Allows to create<>() itself.

  explicit SimpleVariableConstructionContext(const DeclStmt *DS)
      : VariableConstructionContext(ConstructionContext::SimpleVariableKind,
                                    DS) {}

public:
  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == SimpleVariableKind;
  }
};

/// Represents construction into a simple variable with an initializer syntax,
/// with a single constructor, eg. T var = makeT();. Such construction context
/// may only appear in C++17 because previously it was split into a temporary
/// object constructor and an elidable simple variable copy-constructor and
/// we were producing separate construction contexts for these constructors.
/// In C++17 we have a single construction context that combines both.
/// Note that if the object has trivial destructor, then this code is
/// indistinguishable from a simple variable constructor on the AST level;
/// in this case we provide a simple variable construction context.
class CXX17ElidedCopyVariableConstructionContext
    : public VariableConstructionContext {
  const CXXBindTemporaryExpr *BTE;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit CXX17ElidedCopyVariableConstructionContext(
      const DeclStmt *DS, const CXXBindTemporaryExpr *BTE)
      : VariableConstructionContext(CXX17ElidedCopyVariableKind, DS), BTE(BTE) {
    assert(BTE);
  }

public:
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == CXX17ElidedCopyVariableKind;
  }
};

// An abstract base class for constructor-initializer-based constructors.
class ConstructorInitializerConstructionContext : public ConstructionContext {
  const CXXCtorInitializer *I;

protected:
  explicit ConstructorInitializerConstructionContext(
      ConstructionContext::Kind K, const CXXCtorInitializer *I)
      : ConstructionContext(K), I(I) {
    assert(classof(this));
    assert(I);
  }

public:
  const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() >= INITIALIZER_BEGIN &&
           CC->getKind() <= INITIALIZER_END;
  }
};

/// Represents construction into a field or a base class within a bigger object
/// via a constructor initializer, eg. T(): field(123) { ... }.
class SimpleConstructorInitializerConstructionContext
    : public ConstructorInitializerConstructionContext {
  friend class ConstructionContext; // Allows to create<>() itself.

  explicit SimpleConstructorInitializerConstructionContext(
      const CXXCtorInitializer *I)
      : ConstructorInitializerConstructionContext(
            ConstructionContext::SimpleConstructorInitializerKind, I) {}

public:
  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == SimpleConstructorInitializerKind;
  }
};

/// Represents construction into a field or a base class within a bigger object
/// via a constructor initializer, with a single constructor, eg.
/// T(): field(Field(123)) { ... }. Such construction context may only appear
/// in C++17 because previously it was split into a temporary object constructor
/// and an elidable simple constructor-initializer copy-constructor and we were
/// producing separate construction contexts for these constructors. In C++17
/// we have a single construction context that combines both. Note that if the
/// object has trivial destructor, then this code is indistinguishable from
/// a simple constructor-initializer constructor on the AST level; in this case
/// we provide a simple constructor-initializer construction context.
class CXX17ElidedCopyConstructorInitializerConstructionContext
    : public ConstructorInitializerConstructionContext {
  const CXXBindTemporaryExpr *BTE;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit CXX17ElidedCopyConstructorInitializerConstructionContext(
      const CXXCtorInitializer *I, const CXXBindTemporaryExpr *BTE)
      : ConstructorInitializerConstructionContext(
            CXX17ElidedCopyConstructorInitializerKind, I),
        BTE(BTE) {
    assert(BTE);
  }

public:
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == CXX17ElidedCopyConstructorInitializerKind;
  }
};

/// Represents immediate initialization of memory allocated by operator new,
/// eg. new T(123);.
class NewAllocatedObjectConstructionContext : public ConstructionContext {
  const CXXNewExpr *NE;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit NewAllocatedObjectConstructionContext(const CXXNewExpr *NE)
      : ConstructionContext(ConstructionContext::NewAllocatedObjectKind),
        NE(NE) {
    assert(NE);
  }

public:
  const CXXNewExpr *getCXXNewExpr() const { return NE; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == NewAllocatedObjectKind;
  }
};

/// Represents a temporary object, eg. T(123), that does not immediately cross
/// function boundaries "by value"; constructors that construct function
/// value-type arguments or values that are immediately returned from the
/// function that returns a value receive separate construction context kinds.
class TemporaryObjectConstructionContext : public ConstructionContext {
  const CXXBindTemporaryExpr *BTE;
  const MaterializeTemporaryExpr *MTE;

protected:
  explicit TemporaryObjectConstructionContext(
      ConstructionContext::Kind K, const CXXBindTemporaryExpr *BTE,
      const MaterializeTemporaryExpr *MTE)
      : ConstructionContext(K), BTE(BTE), MTE(MTE) {
    // Both BTE and MTE can be null here, all combinations possible.
    // Even though for now at least one should be non-null, we simply haven't
    // implemented the other case yet (this would be a temporary in the middle
    // of nowhere that doesn't have a non-trivial destructor).
  }

public:
  /// CXXBindTemporaryExpr here is non-null as long as the temporary has
  /// a non-trivial destructor.
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const {
    return BTE;
  }

  /// MaterializeTemporaryExpr is non-null as long as the temporary is actually
  /// used after construction, eg. by binding to a reference (lifetime
  /// extension), accessing a field, calling a method, or passing it into
  /// a function (an elidable copy or move constructor would be a common
  /// example) by reference.
  const MaterializeTemporaryExpr *getMaterializedTemporaryExpr() const {
    return MTE;
  }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() >= TEMPORARY_BEGIN && CC->getKind() <= TEMPORARY_END;
  }
};

/// Represents a temporary object that is not constructed for the purpose of
/// being immediately copied/moved by an elidable copy/move-constructor.
/// This includes temporary objects "in the middle of nowhere" like T(123) and
/// lifetime-extended temporaries.
class SimpleTemporaryObjectConstructionContext
    : public TemporaryObjectConstructionContext {
  friend class ConstructionContext; // Allows to create<>() itself.

  explicit SimpleTemporaryObjectConstructionContext(
      const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE)
      : TemporaryObjectConstructionContext(
            ConstructionContext::SimpleTemporaryObjectKind, BTE, MTE) {}

public:
  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == SimpleTemporaryObjectKind;
  }
};

/// Represents a temporary object that is constructed for the sole purpose
/// of being immediately copied by an elidable copy/move constructor.
/// For example, T t = T(123); includes a temporary T(123) that is immediately
/// copied to variable t. In such cases the elidable copy can (but not
/// necessarily should) be omitted ("elided") accodring to the rules of the
/// language; the constructor would then construct variable t directly.
/// This construction context contains information of the elidable constructor
/// and its respective construction context.
class ElidedTemporaryObjectConstructionContext
    : public TemporaryObjectConstructionContext {
  const CXXConstructExpr *ElidedCE;
  const ConstructionContext *ElidedCC;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit ElidedTemporaryObjectConstructionContext(
      const CXXBindTemporaryExpr *BTE, const MaterializeTemporaryExpr *MTE,
      const CXXConstructExpr *ElidedCE, const ConstructionContext *ElidedCC)
      : TemporaryObjectConstructionContext(
            ConstructionContext::ElidedTemporaryObjectKind, BTE, MTE),
        ElidedCE(ElidedCE), ElidedCC(ElidedCC) {
    // Elided constructor and its context should be either both specified
    // or both unspecified. In the former case, the constructor must be
    // elidable.
    assert(ElidedCE && ElidedCE->isElidable() && ElidedCC);
  }

public:
  const CXXConstructExpr *getConstructorAfterElision() const {
    return ElidedCE;
  }

  const ConstructionContext *getConstructionContextAfterElision() const {
    return ElidedCC;
  }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == ElidedTemporaryObjectKind;
  }
};

class ReturnedValueConstructionContext : public ConstructionContext {
  const ReturnStmt *RS;

protected:
  explicit ReturnedValueConstructionContext(ConstructionContext::Kind K,
                                            const ReturnStmt *RS)
      : ConstructionContext(K), RS(RS) {
    assert(classof(this));
    assert(RS);
  }

public:
  const ReturnStmt *getReturnStmt() const { return RS; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() >= RETURNED_VALUE_BEGIN &&
           CC->getKind() <= RETURNED_VALUE_END;
  }
};

/// Represents a temporary object that is being immediately returned from a
/// function by value, eg. return t; or return T(123);. In this case there is
/// always going to be a constructor at the return site. However, the usual
/// temporary-related bureaucracy (CXXBindTemporaryExpr,
/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
class SimpleReturnedValueConstructionContext
    : public ReturnedValueConstructionContext {
  friend class ConstructionContext; // Allows to create<>() itself.

  explicit SimpleReturnedValueConstructionContext(const ReturnStmt *RS)
      : ReturnedValueConstructionContext(
            ConstructionContext::SimpleReturnedValueKind, RS) {}

public:
  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == SimpleReturnedValueKind;
  }
};

/// Represents a temporary object that is being immediately returned from a
/// function by value, eg. return t; or return T(123); in C++17.
/// In C++17 there is not going to be an elidable copy constructor at the
/// return site.  However, the usual temporary-related bureaucracy (CXXBindTemporaryExpr,
/// MaterializeTemporaryExpr) is normally located in the caller function's AST.
/// Note that if the object has trivial destructor, then this code is
/// indistinguishable from a simple returned value constructor on the AST level;
/// in this case we provide a simple returned value construction context.
class CXX17ElidedCopyReturnedValueConstructionContext
    : public ReturnedValueConstructionContext {
  const CXXBindTemporaryExpr *BTE;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit CXX17ElidedCopyReturnedValueConstructionContext(
      const ReturnStmt *RS, const CXXBindTemporaryExpr *BTE)
      : ReturnedValueConstructionContext(
            ConstructionContext::CXX17ElidedCopyReturnedValueKind, RS),
        BTE(BTE) {
    assert(BTE);
  }

public:
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == CXX17ElidedCopyReturnedValueKind;
  }
};

class ArgumentConstructionContext : public ConstructionContext {
  // The call of which the context is an argument.
  const Expr *CE;

  // Which argument we're constructing. Note that when numbering between
  // arguments and parameters is inconsistent (eg., operator calls),
  // this is the index of the argument, not of the parameter.
  unsigned Index;

  // Whether the object needs to be destroyed.
  const CXXBindTemporaryExpr *BTE;

  friend class ConstructionContext; // Allows to create<>() itself.

  explicit ArgumentConstructionContext(const Expr *CE, unsigned Index,
                                       const CXXBindTemporaryExpr *BTE)
      : ConstructionContext(ArgumentKind), CE(CE),
        Index(Index), BTE(BTE) {
    assert(isa<CallExpr>(CE) || isa<CXXConstructExpr>(CE) ||
           isa<ObjCMessageExpr>(CE));
    // BTE is optional.
  }

public:
  const Expr *getCallLikeExpr() const { return CE; }
  unsigned getIndex() const { return Index; }
  const CXXBindTemporaryExpr *getCXXBindTemporaryExpr() const { return BTE; }

  static bool classof(const ConstructionContext *CC) {
    return CC->getKind() == ArgumentKind;
  }
};

} // end namespace clang

#endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
