@@ -45,7 +45,65 @@ namespace clang {
4545 if (Parent)
4646 assert (!isa<LeafExprNode>(Parent) &&
4747 " Parent node cannot be a LeafExprNode" );
48- }
48+ }
49+
50+ virtual ~Node () { }
51+
52+ // Recursively coalesce BinaryOperatorNodes having the same commutative
53+ // and associative operator.
54+ // @param[in] this is the current node of the AST.
55+ // @param[in] Changed indicates whether a node was coalesced. We need this
56+ // to control when to stop recursive coalescing.
57+ // @param[in] Error indicates whether an error occurred during coalescing.
58+ virtual void Coalesce (bool &Changed, bool &Error) = 0;
59+
60+ // Recursively descend a Node to sort the children of all
61+ // BinaryOperatorNodes if the binary operator is commutative.
62+ // @param[in] this is the current node of the AST.
63+ // @param[in] Lex is used to lexicographically compare Exprs and Decls
64+ // that occur within nodes.
65+ virtual void Sort (Lexicographic Lex) = 0;
66+
67+ // Constant fold integer expressions.
68+ // @param[in] this is the current node of the AST.
69+ // @param[in] Changed indicates whether constant folding was done. We need
70+ // this to control when to stop recursive constant folding.
71+ // @param[in] Error indicates whether an error occurred during constant
72+ // folding.
73+ // @param[in] Ctx is used to create constant expressions.
74+ virtual void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx) = 0;
75+
76+ // Compare nodes according to their kind.
77+ // @param[in] this is the current node of the AST.
78+ // @param[in] Other is the node to compare to this.
79+ // @return Returns a Lexicographic::Result indicating the comparison
80+ // between this and Other according to their node kinds.
81+ Result CompareKinds (const Node *Other) const {
82+ if (Kind < Other->Kind )
83+ return Result::LessThan;
84+ if (Kind > Other->Kind )
85+ return Result::GreaterThan;
86+ return Result::Equal;
87+ }
88+
89+ // Compare two nodes lexicographically.
90+ // @param[in] this is the current node of the AST.
91+ // @param[in] Other the node to compare to this.
92+ // @param[in] Lex is used to lexicographically compare Exprs and Decls
93+ // that occur within nodes.
94+ // @return Returns a Lexicographic::Result indicating the comparison
95+ // between this and Other.
96+ virtual Result Compare (const Node *Other, Lexicographic Lex) const = 0;
97+
98+ // Print the node.
99+ // @param[in] this is the current node of the AST.
100+ virtual void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const = 0;
101+
102+ // Cleanup the memory consumed by this node.
103+ // @param[in] this is the current node of the AST.
104+ virtual void Cleanup () {
105+ delete this ;
106+ }
49107 };
50108
51109 class BinaryOperatorNode : public Node {
@@ -69,6 +127,18 @@ namespace clang {
69127 bool IsOpCommutativeAndAssociative () {
70128 return Opc == BO_Add || Opc == BO_Mul;
71129 }
130+
131+ // Determines if the BinaryOperatorNode could be coalesced into its parent.
132+ // @param[in] this is the current node.
133+ // @return Returns true if this can be coalesced into its parent, false
134+ // otherwise.
135+ bool CanCoalesce ();
136+ void Coalesce (bool &Changed, bool &Error);
137+ void Sort (Lexicographic Lex);
138+ void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx);
139+ Result Compare (const Node *Other, Lexicographic Lex) const ;
140+ void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const ;
141+ void Cleanup ();
72142 };
73143
74144 class UnaryOperatorNode : public Node {
@@ -83,6 +153,13 @@ namespace clang {
83153 static bool classof (const Node *N) {
84154 return N->Kind == NodeKind::UnaryOperatorNode;
85155 }
156+
157+ void Coalesce (bool &Changed, bool &Error);
158+ void Sort (Lexicographic Lex);
159+ void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx);
160+ Result Compare (const Node *Other, Lexicographic Lex) const ;
161+ void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const ;
162+ void Cleanup ();
86163 };
87164
88165 class MemberNode : public Node {
@@ -98,6 +175,13 @@ namespace clang {
98175 static bool classof (const Node *N) {
99176 return N->Kind == NodeKind::MemberNode;
100177 }
178+
179+ void Coalesce (bool &Changed, bool &Error);
180+ void Sort (Lexicographic Lex);
181+ void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx);
182+ Result Compare (const Node *Other, Lexicographic Lex) const ;
183+ void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const ;
184+ void Cleanup ();
101185 };
102186
103187 class ImplicitCastNode : public Node {
@@ -112,6 +196,13 @@ namespace clang {
112196 static bool classof (const Node *N) {
113197 return N->Kind == NodeKind::ImplicitCastNode;
114198 }
199+
200+ void Coalesce (bool &Changed, bool &Error);
201+ void Sort (Lexicographic Lex);
202+ void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx);
203+ Result Compare (const Node *Other, Lexicographic Lex) const ;
204+ void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const ;
205+ void Cleanup ();
115206 };
116207
117208 class LeafExprNode : public Node {
@@ -125,6 +216,12 @@ namespace clang {
125216 static bool classof (const Node *N) {
126217 return N->Kind == NodeKind::LeafExprNode;
127218 }
219+
220+ void Coalesce (bool &Changed, bool &Error);
221+ void Sort (Lexicographic Lex);
222+ void ConstantFold (bool &Changed, bool &Error, ASTContext &Ctx);
223+ Result Compare (const Node *Other, Lexicographic Lex) const ;
224+ void PrettyPrint (llvm::raw_ostream &OS, ASTContext &Ctx) const ;
128225 };
129226
130227} // end namespace clang
@@ -143,8 +240,46 @@ namespace clang {
143240 // @param[in] Parent is the parent of the new node.
144241 void Create (Expr *E, Node *Parent = nullptr );
145242
243+ // Create a BinaryOperatorNode for the expression E.
244+ // @param[in] E is the expression whose LHS and RHS subexpressions
245+ // will be added to a new node.
246+ // @param[in] Parent is the parent of the new node.
247+ void CreateBinaryOperator (BinaryOperator *E, Node *Parent);
248+
249+ // Create a UnaryOperatorNode or a LeafExprNode for the expression E.
250+ // @param[in] E is the expression that is used to create a new node.
251+ // @param[in] Parent is the parent of the new node.
252+ void CreateUnaryOperator (UnaryOperator *E, Node *Parent);
253+
254+ // Create a UnaryOperatorNode with the sub expression Child and the
255+ // Deref unary operator.
256+ // @param[in] Child is the expression that is the child of a new node.
257+ // @param[in] Parent is the parent of the new node.
258+ void CreateDereference (Expr *Child, Node *Parent);
259+
260+ // Create a MemberNode for the expression E.
261+ // @param[in] E is the expression whose Base and Field will be added to
262+ // a new node.
263+ // @param[in] Parent is the parent of the new node.
264+ void CreateMember (MemberExpr *E, Node *Parent);
265+
266+ // Create an ImplicitCastNode for the expression.
267+ // @param[in] E is the expression whose CastKind and sub expression will
268+ // be added to a new node.
269+ // @param[in] Parent is the parent of the new node.
270+ void CreateImplicitCast (ImplicitCastExpr *E, Node *Parent);
271+
146272 // Create a BinaryOperatorNode with an addition operator and two children
147273 // (E and 0), and attach the created BinaryOperatorNode to the Parent node.
274+ // This method is used to maintain an invariant that an expression `e` is
275+ // equivalent to `e + 0`. This invariant must hold when:
276+ // 1. `e` is the root expression that is used to create the PreorderAST.
277+ // 2. `e` is the subexpression of a dereference expression. For example:
278+ // a. `*e` and `*(e + 0)` must have the same canonical form.
279+ // b. `e1[e2]` is equivalent to `*(e1 + e2)`, so `*(e1 + e2)` and
280+ // `*(e1 + e2 + 0)` must have the same canonical form.
281+ // c. `e->f`, `*e.f`, `(e + 0)->f`, `*(e + 0).f`, and `e[0].f` must have
282+ // the same canonical form.
148283 // @param[in] E is the expression that is one of the two children of
149284 // the created BinaryOperatorNode (the other child is 0).
150285 // @param[in] Parent is the parent of the created BinaryOperatorNode.
@@ -155,48 +290,6 @@ namespace clang {
155290 // @param[in] Parent is the parent of the node to be attached.
156291 void AttachNode (Node *N, Node *Parent);
157292
158- // Coalesce the BinaryOperatorNode B with its parent. This involves moving
159- // the children (if any) of node B to its parent and then removing B.
160- // @param[in] B is the current node. B should be a BinaryOperatorNode.
161- void CoalesceNode (BinaryOperatorNode *B);
162-
163- // Determines if a BinaryOperatorNode could be coalesced into its parent.
164- // @param[in] B is the current node. B should be a BinaryOperatorNode.
165- // @return Return true if B can be coalesced into its parent, false
166- // otherwise.
167- bool CanCoalesceNode (BinaryOperatorNode *B);
168-
169- // Recursively coalesce BinaryOperatorNodes having the same commutative
170- // and associative operator.
171- // @param[in] N is current node of the AST. Initial value is Root.
172- // @param[in] Changed indicates whether a node was coalesced. We need this
173- // to control when to stop recursive coalescing.
174- void Coalesce (Node *N, bool &Changed);
175-
176- // Recursively descend the PreorderAST to sort the children of all
177- // BinaryOperatorNodes if the binary operator is commutative.
178- // @param[in] N is current node of the AST. Initial value is Root.
179- void Sort (Node *N);
180-
181- // Compare nodes N1 and N2 to sort them. This function is invoked by a
182- // lambda which is passed to the llvm::sort function.
183- // @param[in] N1 is the first node to compare.
184- // @param[in] N2 is the second node to compare.
185- // return A boolean indicating the relative ordering between N1 and N2.
186- bool CompareNodes (const Node *N1, const Node *N2);
187-
188- // Constant fold integer expressions.
189- // @param[in] N is current node of the AST. Initial value is Root.
190- // @param[in] Changed indicates whether constant folding was done. We need
191- // this to control when to stop recursive constant folding.
192- void ConstantFold (Node *N, bool &Changed);
193-
194- // Constant fold integer expressions within a BinaryOperatorNode.
195- // @param[in] N is current node of the AST.
196- // @param[in] Changed indicates whether constant folding was done. We need
197- // this to control when to stop recursive constant folding.
198- void ConstantFoldOperator (BinaryOperatorNode *N, bool &Changed);
199-
200293 // Get the deref offset from the DerefExpr. The offset represents the
201294 // possible amount by which the bounds of an ntptr could be widened.
202295 // @param[in] UpperExpr is the upper bounds expr for the ntptr.
@@ -209,24 +302,9 @@ namespace clang {
209302 bool GetDerefOffset (Node *UpperExpr, Node *DerefExpr,
210303 llvm::APSInt &Offset);
211304
212- // Lexicographically compare two AST nodes N1 and N2.
213- // @param[in] N1 is the first node.
214- // @param[in] N2 is the second node.
215- // @return Returns a Lexicographic::Result indicating the comparison
216- // of N1 and N2.
217- Result Compare (const Node *N1, const Node *N2) const ;
218-
219305 // Set Error in case an error occurs during transformation of the AST.
220306 void SetError () { Error = true ; }
221307
222- // Print the PreorderAST.
223- // @param[in] N is the current node of the AST. Initial value is Root.
224- void PrettyPrint (Node *N);
225-
226- // Cleanup the memory consumed by node N.
227- // @param[in] N is the current node of the AST. Initial value is Root.
228- void Cleanup (Node *N);
229-
230308 public:
231309 PreorderAST (ASTContext &Ctx, Expr *E) :
232310 Ctx (Ctx), Lex(Lexicographic(Ctx, nullptr )), OS(llvm::outs()),
@@ -257,7 +335,9 @@ namespace clang {
257335 // @param[in] P is the second AST.
258336 // @return Returns a Lexicographic::Result indicating the comparison between
259337 // the two ASTs.
260- Result Compare (const PreorderAST P) const { return Compare (Root, P.Root ); }
338+ Result Compare (const PreorderAST P) const {
339+ return Root->Compare (P.Root , Lex);
340+ }
261341
262342 // Check if an error has occurred during transformation of the AST. This
263343 // is intended to be called from outside this class to check if an error
@@ -268,7 +348,7 @@ namespace clang {
268348 // Cleanup the memory consumed by the AST. This is intended to be called
269349 // from outside this class and invokes Cleanup on the root node which
270350 // recursively deletes the AST.
271- void Cleanup () { Cleanup (Root ); }
351+ void Cleanup () { Root-> Cleanup (); }
272352
273353 bool operator <(PreorderAST &Other) const {
274354 return Compare (Other) == Result::LessThan;
0 commit comments