From dbce6c11df75b223f22fbfcab76a9d4352257931 Mon Sep 17 00:00:00 2001 From: Argiris Kirtzidis Date: Tue, 9 Sep 2008 23:47:53 +0000 Subject: [PATCH] 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 --- include/clang/AST/Expr.h | 9 ++++++++- include/clang/AST/ExprCXX.h | 37 +++++++++++++++++++++++++++++++++++++ include/clang/AST/StmtNodes.def | 1 + lib/AST/ExprCXX.cpp | 14 ++++++++++++++ lib/AST/StmtPrinter.cpp | 5 +++++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 5acf4dea3..cfc51cb15 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -206,17 +206,24 @@ public: 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 f0037bf07..915c9e000 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -234,6 +234,43 @@ public: 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(getDecl()); } + const VarDecl *getVarDecl() const { return cast(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 3acf4e6ae..697aa9d70 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -95,6 +95,7 @@ STMT(62, CXXThrowExpr , Expr) 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 cf85ae2d7..2ad65451d 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_begin() { 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 f5806ea5d..3c3e207a0 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -829,6 +829,11 @@ void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) { OS << Node->getType().getAsString() << "()"; } +void +StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) { + PrintRawDecl(E->getVarDecl()); +} + // Obj-C void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { -- 2.11.4.GIT