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;
}
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;
+}
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.
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__.
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 {
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 {
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 {
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"
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
return T->getStmtClass() == ParenExprClass;
}
static bool classof(const ParenExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
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
return T->getStmtClass() == SizeOfAlignOfTypeExprClass;
}
static bool classof(const SizeOfAlignOfTypeExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
};
//===----------------------------------------------------------------------===//
/// 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; }
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.
///
/// 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
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.
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator"
#include <iosfwd>
namespace clang {
// 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