//===- 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