Add new 'CXXConditionDeclExpr' expression node used for a 'condition' declaration, e.g: "if (int x=0) {...}".
It is a subclass of DeclRefExpr and the main difference is that CXXConditionDeclExpr owns the declaration that it references.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56033 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 5acf4de..cfc51cb 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -206,17 +206,24 @@
 class DeclRefExpr : public Expr {
   ValueDecl *D; 
   SourceLocation Loc;
+
+protected:
+  DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) :
+    Expr(SC, t), D(d), Loc(l) {}
+
 public:
   DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) : 
     Expr(DeclRefExprClass, t), D(d), Loc(l) {}
   
   ValueDecl *getDecl() { return D; }
   const ValueDecl *getDecl() const { return D; }
+  SourceLocation getLocation() const { return Loc; }
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
   
   
   static bool classof(const Stmt *T) { 
-    return T->getStmtClass() == DeclRefExprClass; 
+    return T->getStmtClass() == DeclRefExprClass ||
+           T->getStmtClass() == CXXConditionDeclExprClass; 
   }
   static bool classof(const DeclRefExpr *) { return true; }
   
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index f0037bf..915c9e0 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -234,6 +234,43 @@
       CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };
 
+/// CXXConditionDeclExpr - Condition declaration of a if/switch/while/for
+/// statement, e.g: "if (int x = f()) {...}".
+/// The main difference with DeclRefExpr is that CXXConditionDeclExpr owns the
+/// decl that it references.
+///
+class CXXConditionDeclExpr : public DeclRefExpr {
+public:
+  CXXConditionDeclExpr(SourceLocation startLoc,
+                       SourceLocation eqLoc, VarDecl *var)
+    : DeclRefExpr(CXXConditionDeclExprClass, var, var->getType(), startLoc) {}
+
+  virtual void Destroy(ASTContext& Ctx);
+
+  SourceLocation getStartLoc() const { return getLocation(); }
+  
+  VarDecl *getVarDecl() { return cast<VarDecl>(getDecl()); }
+  const VarDecl *getVarDecl() const { return cast<VarDecl>(getDecl()); }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getStartLoc(), getVarDecl()->getInit()->getLocEnd());
+  }
+    
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == CXXConditionDeclExprClass;
+  }
+  static bool classof(const CXXConditionDeclExpr *) { return true; }
+      
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end();
+
+  // FIXME: Implement these.
+  //virtual void EmitImpl(llvm::Serializer& S) const;
+  //static CXXConditionDeclExpr *
+  //    CreateImpl(llvm::Deserializer& D, ASTContext& C);
+};
+
 }  // end namespace clang
 
 #endif
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 3acf4e6..697aa9d 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -95,6 +95,7 @@
 STMT(63, CXXDefaultArgExpr    , Expr)
 STMT(64, CXXFunctionalCastExpr, CastExpr)
 STMT(65, CXXZeroInitValueExpr , Expr)
+STMT(66, CXXConditionDeclExpr , DeclRefExpr)
 
 // Obj-C Expressions.
 STMT(70, ObjCStringLiteral    , Expr)
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index cf85ae2..2ad6545 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -14,6 +14,12 @@
 #include "clang/AST/ExprCXX.h"
 using namespace clang;
 
+void CXXConditionDeclExpr::Destroy(ASTContext& C) {

+  getVarDecl()->Destroy(C);

+  delete this;

+}

+
+
 //===----------------------------------------------------------------------===//
 //  Child Iterators for iterating over subexpressions/substatements
 //===----------------------------------------------------------------------===//
@@ -53,3 +59,11 @@
 Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
   return child_iterator();
 }
+
+// CXXConditionDeclExpr
+Stmt::child_iterator CXXConditionDeclExpr::child_begin() {
+  return getVarDecl();
+}
+Stmt::child_iterator CXXConditionDeclExpr::child_end() {
+  return child_iterator();
+}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index f5806ea..3c3e207 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -829,6 +829,11 @@
   OS << Node->getType().getAsString() << "()";
 }
 
+void
+StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
+  PrintRawDecl(E->getVarDecl());
+}
+
 // Obj-C 
 
 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {