[cfe-commits] r41363 - in /cfe/trunk: AST/Expr.cpp include/clang/AST/Expr.h include/clang/AST/Stmt.h
Ted Kremenek
kremenek at apple.com
Fri Aug 24 11:13:47 PDT 2007
Author: kremenek
Date: Fri Aug 24 13:13:47 2007
New Revision: 41363
URL: http://llvm.org/viewvc/llvm-project?rev=41363&view=rev
Log:
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.
Modified:
cfe/trunk/AST/Expr.cpp
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/Stmt.h
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=41363&r1=41362&r2=41363&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Fri Aug 24 13:13:47 2007
@@ -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;
+}
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=41363&r1=41362&r2=41363&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Aug 24 13:13:47 2007
@@ -36,7 +36,7 @@
public:
QualType getType() const { return TR; }
void setType(QualType t) { TR = t; }
-
+
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
@@ -132,6 +132,10 @@
return T->getStmtClass() == DeclRefExprClass;
}
static bool classof(const DeclRefExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__.
@@ -157,7 +161,11 @@
static bool classof(const Stmt *T) {
return T->getStmtClass() == PreDefinedExprClass;
}
- static bool classof(const PreDefinedExpr *) { return true; }
+ static bool classof(const PreDefinedExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
class IntegerLiteral : public Expr {
@@ -177,6 +185,10 @@
return T->getStmtClass() == IntegerLiteralClass;
}
static bool classof(const IntegerLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
class CharacterLiteral : public Expr {
@@ -197,6 +209,10 @@
return T->getStmtClass() == CharacterLiteralClass;
}
static bool classof(const CharacterLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
class FloatingLiteral : public Expr {
@@ -214,6 +230,10 @@
return T->getStmtClass() == FloatingLiteralClass;
}
static bool classof(const FloatingLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// StringLiteral - This represents a string literal expression, e.g. "foo"
@@ -244,6 +264,10 @@
return T->getStmtClass() == StringLiteralClass;
}
static bool classof(const StringLiteral *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
@@ -263,6 +287,10 @@
return T->getStmtClass() == ParenExprClass;
}
static bool classof(const ParenExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
@@ -326,6 +354,10 @@
return T->getStmtClass() == UnaryOperatorClass;
}
static bool classof(const UnaryOperator *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
@@ -350,6 +382,10 @@
return T->getStmtClass() == SizeOfAlignOfTypeExprClass;
}
static bool classof(const SizeOfAlignOfTypeExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
//===----------------------------------------------------------------------===//
@@ -358,38 +394,49 @@
/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
class ArraySubscriptExpr : public Expr {
- Expr *LHS, *RHS;
+ enum { LHS, RHS, END_EXPR=2 };
+ Expr* SubExprs[END_EXPR];
SourceLocation RBracketLoc;
public:
ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t,
SourceLocation rbracketloc) :
Expr(ArraySubscriptExprClass, t),
- LHS(lhs), RHS(rhs), RBracketLoc(rbracketloc) {}
+ RBracketLoc(rbracketloc) {
+ SubExprs[LHS] = lhs;
+ SubExprs[RHS] = rhs;
+ }
/// An array access can be written A[4] or 4[A] (both are equivalent).
/// - getBase() and getIdx() always present the normalized view: A[4].
/// In this case getBase() returns "A" and getIdx() returns "4".
/// - getLHS() and getRHS() present the syntactic view. e.g. for
/// 4[A] getLHS() returns "4".
+
+ Expr *getLHS() { return SubExprs[LHS]; }
+ const Expr *getLHS() const { return SubExprs[LHS]; }
- Expr *getBase() { return (LHS->getType()->isIntegerType()) ? RHS : LHS; }
+ Expr *getRHS() { return SubExprs[RHS]; }
+ const Expr *getRHS() const { return SubExprs[RHS]; }
+
+ Expr *getBase() {
+ return (getLHS()->getType()->isIntegerType()) ? getRHS() : getLHS();
+ }
+
const Expr *getBase() const {
- return (LHS->getType()->isIntegerType()) ? RHS : LHS;
+ return (getLHS()->getType()->isIntegerType()) ? getRHS() : getLHS();
}
- Expr *getIdx() { return (LHS->getType()->isIntegerType()) ? LHS : RHS; }
- const Expr *getIdx() const {
- return (LHS->getType()->isIntegerType()) ? LHS : RHS;
+ Expr *getIdx() {
+ return (getLHS()->getType()->isIntegerType()) ? getLHS() : getRHS();
}
- Expr *getLHS() { return LHS; }
- const Expr *getLHS() const { return LHS; }
-
- Expr *getRHS() { return RHS; }
- const Expr *getRHS() const { return RHS; }
+ const Expr *getIdx() const {
+ return (getLHS()->getType()->isIntegerType()) ? getLHS() : getRHS();
+ }
+
SourceRange getSourceRange() const {
- return SourceRange(LHS->getLocStart(), RBracketLoc);
+ return SourceRange(getLHS()->getLocStart(), RBracketLoc);
}
virtual SourceLocation getExprLoc() const { return RBracketLoc; }
@@ -397,25 +444,29 @@
return T->getStmtClass() == ArraySubscriptExprClass;
}
static bool classof(const ArraySubscriptExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// CallExpr - [C99 6.5.2.2] Function Calls.
///
class CallExpr : public Expr {
- Expr *Fn;
- Expr **Args;
+ enum { FN=0, ARGS_START=1 };
+ Expr **SubExprs;
unsigned NumArgs;
SourceLocation RParenLoc;
public:
CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
SourceLocation rparenloc);
~CallExpr() {
- delete [] Args;
+ delete [] SubExprs;
}
- const Expr *getCallee() const { return Fn; }
- Expr *getCallee() { return Fn; }
+ const Expr *getCallee() const { return SubExprs[FN]; }
+ Expr *getCallee() { return SubExprs[FN]; }
/// getNumArgs - Return the number of actual arguments to this call.
///
@@ -424,11 +475,11 @@
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
assert(Arg < NumArgs && "Arg access out of range!");
- return Args[Arg];
+ return SubExprs[Arg+ARGS_START];
}
const Expr *getArg(unsigned Arg) const {
assert(Arg < NumArgs && "Arg access out of range!");
- return Args[Arg];
+ return SubExprs[Arg+ARGS_START];
}
/// getNumCommas - Return the number of commas that must have been present in
@@ -438,13 +489,17 @@
bool isBuiltinClassifyType(llvm::APSInt &Result) const;
SourceRange getSourceRange() const {
- return SourceRange(Fn->getLocStart(), RParenLoc);
+ return SourceRange(getCallee()->getLocStart(), RParenLoc);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CallExprClass;
}
static bool classof(const CallExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
/// MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=41363&r1=41362&r2=41363&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri Aug 24 13:13:47 2007
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator"
#include <iosfwd>
namespace clang {
@@ -67,6 +68,49 @@
// Implement isa<T> support.
static bool classof(const Stmt *) { return true; }
+
+
+ /// Child Iterators: All subclasses must implement child_begin and child_end
+ /// to permit easy iteration over the substatements/subexpessions of an
+ /// AST node. This permits easy iteration over all nodes in the AST.
+ typedef Stmt** child_iterator;
+ typedef Stmt* const * const_child_iterator;
+
+ typedef std::reverse_iterator<child_iterator>
+ reverse_child_iterator;
+ typedef std::reverse_iterator<const_child_iterator>
+ const_reverse_child_iterator;
+
+ // FIXME: Still implementing the the child_begin and child_end functions
+ // for all subclasses.
+#if 0
+ virtual child_iterator child_begin() = 0;
+ virtual child_iterator child_end() = 0;
+
+ const_child_iterator child_begin() const {
+ return (child_iterator) const_cast<Stmt*>(this)->child_begin();
+ }
+
+ const_child_iterator child_end() const {
+ return (child_iterator) const_cast<Stmt*>(this)->child_end();
+ }
+
+ reverse_child_iterator child_rbegin() {
+ return reverse_child_iterator(child_end());
+ }
+
+ reverse_child_iterator child_rend() {
+ return reverse_child_iterator(child_begin());
+ }
+
+ const_reverse_child_iterator child_rbegin() const {
+ return const_reverse_child_iterator(child_end());
+ }
+
+ const_reverse_child_iterator child_rend() const {
+ return const_reverse_child_iterator(child_begin());
+ }
+#endif
};
/// DeclStmt - Adaptor class for mixing declarations with statements and
More information about the cfe-commits
mailing list