//===- CFG.h - Classes for representing and building CFGs -------*- 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 CFG and CFGBuilder classes for representing and // building Control-Flow Graphs (CFGs) from ASTs. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_CFG_H #define LLVM_CLANG_ANALYSIS_CFG_H #include "clang/AST/Attr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/Analysis/ConstructionContext.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/raw_ostream.h" #include <bitset> #include <cassert> #include <cstddef> #include <iterator> #include <memory> #include <optional> #include <vector> namespace clang { class ASTContext; class BinaryOperator; class CFG; class CXXBaseSpecifier; class CXXBindTemporaryExpr; class CXXCtorInitializer; class CXXDeleteExpr; class CXXDestructorDecl; class CXXNewExpr; class CXXRecordDecl; class Decl; class FieldDecl; class LangOptions; class VarDecl; /// Represents a top-level expression in a basic block. class CFGElement { … }; class CFGStmt : public CFGElement { … }; /// Represents C++ constructor call. Maintains information necessary to figure /// out what memory is being initialized by the constructor expression. For now /// this is only used by the analyzer's CFG. class CFGConstructor : public CFGStmt { … }; /// Represents a function call that returns a C++ object by value. This, like /// constructor, requires a construction context in order to understand the /// storage of the returned object . In C such tracking is not necessary because /// no additional effort is required for destroying the object or modeling copy /// elision. Like CFGConstructor, this element is for now only used by the /// analyzer's CFG. class CFGCXXRecordTypedCall : public CFGStmt { … }; /// Represents C++ base or member initializer from constructor's initialization /// list. class CFGInitializer : public CFGElement { … }; /// Represents C++ allocator call. class CFGNewAllocator : public CFGElement { … }; /// Represents the point where a loop ends. /// This element is only produced when building the CFG for the static /// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag. /// /// Note: a loop exit element can be reached even when the loop body was never /// entered. class CFGLoopExit : public CFGElement { … }; /// Represents the point where the lifetime of an automatic object ends class CFGLifetimeEnds : public CFGElement { … }; /// Represents beginning of a scope implicitly generated /// by the compiler on encountering a CompoundStmt class CFGScopeBegin : public CFGElement { … }; /// Represents end of a scope implicitly generated by /// the compiler after the last Stmt in a CompoundStmt's body class CFGScopeEnd : public CFGElement { … }; /// Represents C++ object destructor implicitly generated by compiler on various /// occasions. class CFGImplicitDtor : public CFGElement { … }; class CFGCleanupFunction final : public CFGElement { … }; /// Represents C++ object destructor implicitly generated for automatic object /// or temporary bound to const reference at the point of leaving its local /// scope. class CFGAutomaticObjDtor: public CFGImplicitDtor { … }; /// Represents C++ object destructor generated from a call to delete. class CFGDeleteDtor : public CFGImplicitDtor { … }; /// Represents C++ object destructor implicitly generated for base object in /// destructor. class CFGBaseDtor : public CFGImplicitDtor { … }; /// Represents C++ object destructor implicitly generated for member object in /// destructor. class CFGMemberDtor : public CFGImplicitDtor { … }; /// Represents C++ object destructor implicitly generated at the end of full /// expression for temporary object. class CFGTemporaryDtor : public CFGImplicitDtor { … }; /// Represents CFGBlock terminator statement. /// class CFGTerminator { … }; /// Represents a single basic block in a source-level CFG. /// It consists of: /// /// (1) A set of statements/expressions (which may contain subexpressions). /// (2) A "terminator" statement (not in the set of statements). /// (3) A list of successors and predecessors. /// /// Terminator: The terminator represents the type of control-flow that occurs /// at the end of the basic block. The terminator is a Stmt* referring to an /// AST node that has control-flow: if-statements, breaks, loops, etc. /// If the control-flow is conditional, the condition expression will appear /// within the set of statements in the block (usually the last statement). /// /// Predecessors: the order in the set of predecessors is arbitrary. /// /// Successors: the order in the set of successors is NOT arbitrary. We /// currently have the following orderings based on the terminator: /// /// Terminator | Successor Ordering /// ------------------|------------------------------------ /// if | Then Block; Else Block /// ? operator | LHS expression; RHS expression /// logical and/or | expression that consumes the op, RHS /// vbase inits | already handled by the most derived class; not yet /// /// But note that any of that may be NULL in case of optimized-out edges. class CFGBlock { … }; /// CFGCallback defines methods that should be called when a logical /// operator error is found when building the CFG. class CFGCallback { … }; /// Represents a source-level, intra-procedural CFG that represents the /// control-flow of a Stmt. The Stmt can represent an entire function body, /// or a single expression. A CFG will always contain one empty block that /// represents the Exit point of the CFG. A CFG will also contain a designated /// Entry block. The CFG solely represents control-flow; it consists of /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG /// was constructed from. class CFG { … }; Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE); } // namespace clang //===----------------------------------------------------------------------===// // GraphTraits specializations for CFG basic block graphs (source-level CFGs) //===----------------------------------------------------------------------===// namespace llvm { /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from /// CFGTerminator to a specific Stmt class. template <> struct simplify_type< ::clang::CFGTerminator> { … }; // Traits for: CFGBlock template <> struct GraphTraits< ::clang::CFGBlock *> { … }; template <> struct GraphTraits< const ::clang::CFGBlock *> { … }; template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> { … }; template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> { … }; // Traits for: CFG template <> struct GraphTraits< ::clang::CFG* > : public GraphTraits< ::clang::CFGBlock *> { … }; template <> struct GraphTraits<const ::clang::CFG* > : public GraphTraits<const ::clang::CFGBlock *> { … }; template <> struct GraphTraits<Inverse< ::clang::CFG *>> : public GraphTraits<Inverse< ::clang::CFGBlock *>> { … }; template <> struct GraphTraits<Inverse<const ::clang::CFG *>> : public GraphTraits<Inverse<const ::clang::CFGBlock *>> { … }; } // namespace llvm #endif // LLVM_CLANG_ANALYSIS_CFG_H