1 | //===-- ASTOps.h -------------------------------*- 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 | // Operations on AST nodes that are used in flow-sensitive analysis. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H |
14 | #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H |
15 | |
16 | #include "clang/AST/Decl.h" |
17 | #include "clang/AST/Expr.h" |
18 | #include "clang/AST/Type.h" |
19 | #include "clang/Analysis/FlowSensitive/StorageLocation.h" |
20 | #include "llvm/ADT/DenseSet.h" |
21 | #include "llvm/ADT/SetVector.h" |
22 | |
23 | namespace clang { |
24 | namespace dataflow { |
25 | |
26 | /// Skip past nodes that the CFG does not emit. These nodes are invisible to |
27 | /// flow-sensitive analysis, and should be ignored as they will effectively not |
28 | /// exist. |
29 | /// |
30 | /// * `ParenExpr` - The CFG takes the operator precedence into account, but |
31 | /// otherwise omits the node afterwards. |
32 | /// |
33 | /// * `ExprWithCleanups` - The CFG will generate the appropriate calls to |
34 | /// destructors and then omit the node. |
35 | /// |
36 | const Expr &ignoreCFGOmittedNodes(const Expr &E); |
37 | const Stmt &ignoreCFGOmittedNodes(const Stmt &S); |
38 | |
39 | /// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic |
40 | /// iteration order. |
41 | using FieldSet = llvm::SmallSetVector<const FieldDecl *, 4>; |
42 | |
43 | /// Returns the set of all fields in the type. |
44 | FieldSet getObjectFields(QualType Type); |
45 | |
46 | /// Returns whether `Fields` and `FieldLocs` contain the same fields. |
47 | bool containsSameFields(const FieldSet &Fields, |
48 | const RecordStorageLocation::FieldToLoc &FieldLocs); |
49 | |
50 | /// Helper class for initialization of a record with an `InitListExpr`. |
51 | /// `InitListExpr::inits()` contains the initializers for both the base classes |
52 | /// and the fields of the record; this helper class separates these out into two |
53 | /// different lists. In addition, it deals with special cases associated with |
54 | /// unions. |
55 | class RecordInitListHelper { |
56 | public: |
57 | // `InitList` must have record type. |
58 | RecordInitListHelper(const InitListExpr *InitList); |
59 | RecordInitListHelper(const CXXParenListInitExpr *ParenInitList); |
60 | |
61 | // Base classes with their associated initializer expressions. |
62 | ArrayRef<std::pair<const CXXBaseSpecifier *, Expr *>> base_inits() const { |
63 | return BaseInits; |
64 | } |
65 | |
66 | // Fields with their associated initializer expressions. |
67 | ArrayRef<std::pair<const FieldDecl *, Expr *>> field_inits() const { |
68 | return FieldInits; |
69 | } |
70 | |
71 | private: |
72 | RecordInitListHelper(QualType Ty, std::vector<const FieldDecl *> Fields, |
73 | ArrayRef<Expr *> Inits); |
74 | |
75 | SmallVector<std::pair<const CXXBaseSpecifier *, Expr *>> BaseInits; |
76 | SmallVector<std::pair<const FieldDecl *, Expr *>> FieldInits; |
77 | |
78 | // We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a |
79 | // member variable because we store a pointer to it in `FieldInits`. |
80 | std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion; |
81 | }; |
82 | |
83 | /// A collection of several types of declarations, all referenced from the same |
84 | /// function. |
85 | struct ReferencedDecls { |
86 | /// Non-static member variables. |
87 | FieldSet Fields; |
88 | /// All variables with static storage duration, notably including static |
89 | /// member variables and static variables declared within a function. |
90 | llvm::DenseSet<const VarDecl *> Globals; |
91 | /// Free functions and member functions which are referenced (but not |
92 | /// necessarily called). |
93 | llvm::DenseSet<const FunctionDecl *> Functions; |
94 | }; |
95 | |
96 | /// Returns declarations that are declared in or referenced from `FD`. |
97 | ReferencedDecls getReferencedDecls(const FunctionDecl &FD); |
98 | |
99 | /// Returns declarations that are declared in or referenced from `S`. |
100 | ReferencedDecls getReferencedDecls(const Stmt &S); |
101 | |
102 | } // namespace dataflow |
103 | } // namespace clang |
104 | |
105 | #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H |
106 | |