Began implementing "child iterator" interface for Stmts and Exprs. Each
subclass of Stmt will implement child_begin() and child_end(), which will
be used to iterate over all the children (subexpressions/substatements) of
a Stmt object. This will provide for easy traversal over the AST, which
is useful for a variety of purposes.
None of the interfaces to subclasses of Stmt will be changed (other than
adding the child_begin and child_end methods).
The only caveat is that the implementation of subclasses of Stmt will require
colocating all substatements (subexpressions) in an array. This is because
we define child_iterator as Stmt**. All accessor methods to subexpressions
will need to be altered to reflect this new implementation.
This patch includes the typedefs for child_iterator, as well the implementation
for child_begin/child_end for the primary expressions and some postfix
expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41363 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/Expr.cpp b/AST/Expr.cpp
index 8701b9b..ce5a8ce 100644
--- a/AST/Expr.cpp
+++ b/AST/Expr.cpp
@@ -78,10 +78,11 @@
CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation rparenloc)
- : Expr(CallExprClass, t), Fn(fn), NumArgs(numargs) {
- Args = new Expr*[numargs];
+ : Expr(CallExprClass, t), NumArgs(numargs) {
+ SubExprs = new Expr*[numargs+1];
+ SubExprs[FN] = fn;
for (unsigned i = 0; i != numargs; ++i)
- Args[i] = args[i];
+ SubExprs[i+ARGS_START] = args[i];
RParenLoc = rparenloc;
}
@@ -711,3 +712,75 @@
return Result;
}
+//===----------------------------------------------------------------------===//
+// Child Iterators for iterating over subexpressions/substatements
+//===----------------------------------------------------------------------===//
+
+// DeclRefExpr
+Stmt::child_iterator DeclRefExpr::child_begin() { return NULL; }
+Stmt::child_iterator DeclRefExpr::child_end() { return NULL; }
+
+// PreDefinedExpr
+Stmt::child_iterator PreDefinedExpr::child_begin() { return NULL; }
+Stmt::child_iterator PreDefinedExpr::child_end() { return NULL; }
+
+// IntegerLiteral
+Stmt::child_iterator IntegerLiteral::child_begin() { return NULL; }
+Stmt::child_iterator IntegerLiteral::child_end() { return NULL; }
+
+// CharacterLiteral
+Stmt::child_iterator CharacterLiteral::child_begin() { return NULL; }
+Stmt::child_iterator CharacterLiteral::child_end() { return NULL; }
+
+// FloatingLiteral
+Stmt::child_iterator FloatingLiteral::child_begin() { return NULL; }
+Stmt::child_iterator FloatingLiteral::child_end() { return NULL; }
+
+// StringLiteral
+Stmt::child_iterator StringLiteral::child_begin() { return NULL; }
+Stmt::child_iterator StringLiteral::child_end() { return NULL; }
+
+// ParenExpr
+Stmt::child_iterator ParenExpr::child_begin() {
+ return reinterpret_cast<Stmt**>(&Val);
+}
+
+Stmt::child_iterator ParenExpr::child_end() {
+ return child_begin()+1;
+}
+
+// UnaryOperator
+Stmt::child_iterator UnaryOperator::child_begin() {
+ return reinterpret_cast<Stmt**>(&Val);
+}
+
+Stmt::child_iterator UnaryOperator::child_end() {
+ return child_begin()+1;
+}
+
+// SizeOfAlignOfTypeExpr
+Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() {
+ return NULL;
+}
+
+Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() {
+ return NULL;
+}
+
+// ArraySubscriptExpr
+Stmt::child_iterator ArraySubscriptExpr::child_begin() {
+ return reinterpret_cast<Stmt**>(&SubExprs);
+}
+
+Stmt::child_iterator ArraySubscriptExpr::child_end() {
+ return child_begin()+END_EXPR;
+}
+
+// CallExpr
+Stmt::child_iterator CallExpr::child_begin() {
+ return reinterpret_cast<Stmt**>(&SubExprs);
+}
+
+Stmt::child_iterator CallExpr::child_end() {
+ return child_begin()+NumArgs+ARGS_START;
+}