llvm/clang/include/clang/Analysis/ConstructionContext.h

//===- 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 {};

/// 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 {};


/// 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 {};

/// An abstract base class for local variable constructors.
class VariableConstructionContext : public ConstructionContext {};

/// 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 {};

/// 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 {};

// An abstract base class for constructor-initializer-based constructors.
class ConstructorInitializerConstructionContext : public ConstructionContext {};

/// 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 {};

/// 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 {};

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

/// 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 {};

/// 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 {};

/// 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") according 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 {};

class ReturnedValueConstructionContext : public ConstructionContext {};

/// 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 {};

/// 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 {};

class ArgumentConstructionContext : public ConstructionContext {};

class LambdaCaptureConstructionContext : public ConstructionContext {};

} // end namespace clang

#endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H