[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