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.

llvm-svn: 56033
This commit is contained in:
Argyrios Kyrtzidis 2008-09-09 23:47:53 +00:00
parent 0fff397a13
commit aa479138ea
5 changed files with 65 additions and 1 deletions

View File

@ -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; }

View File

@ -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<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

View File

@ -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)

View File

@ -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();
}

View File

@ -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) {