From: Anders Carlsson Date: Thu, 23 Apr 2009 02:32:43 +0000 (+0000) Subject: Add a CXXConstructExpr that represents an implicit call to a C++ constructor. I think... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e349bea668622ef31bd51a229960a73d69940709;p=clang Add a CXXConstructExpr that represents an implicit call to a C++ constructor. I think CXXTemporaryObjectExpr is going to become a subclass of CXXConstructExpr, since CXXTemporaryObjectExpr represents a syntactic temporary, for example T() git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69854 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 7a68d8aef0..6ef7513e05 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -890,10 +890,57 @@ public: virtual StmtIterator child_end(); }; +/// CXXConstructExpr - Represents a call to a C++ constructor. +class CXXConstructExpr : public Expr { + VarDecl *VD; + CXXConstructorDecl *Constructor; + + bool Elidable; + + Stmt **Args; + unsigned NumArgs; + + CXXConstructExpr(ASTContext &C, VarDecl *vd, QualType T, + CXXConstructorDecl *d, bool elidable, + Expr **args, unsigned numargs); + ~CXXConstructExpr() { } + +public: + static CXXConstructExpr *Create(ASTContext &C, VarDecl *VD, QualType T, + CXXConstructorDecl *D, bool Elidable, + Expr **Args, unsigned NumArgs); + + void Destroy(ASTContext &C); + + const VarDecl* getVarDecl() const { return VD; } + const CXXConstructorDecl* getConstructor() const { return Constructor; } + + typedef ExprIterator arg_iterator; + typedef ConstExprIterator const_arg_iterator; + + arg_iterator arg_begin() { return Args; } + arg_iterator arg_end() { return Args + NumArgs; } + const_arg_iterator arg_begin() const { return Args; } + const_arg_iterator arg_end() const { return Args + NumArgs; } + + unsigned getNumArgs() const { return NumArgs; } + + virtual SourceRange getSourceRange() const { return SourceRange(); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXConstructExprClass; + } + static bool classof(const CXXConstructExpr *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + +/// CXXDestroyExpr - Represents an implicit call to a C++ destructor. class CXXDestroyExpr : public Expr { VarDecl *VD; -protected: CXXDestroyExpr(VarDecl* vd, QualType T) : Expr(CXXDestroyExprClass, T, false, vd->getType()->isDependentType()), VD(vd) { } diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index 84ee6b3908..b9c6aa28dd 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -120,6 +120,7 @@ STMT(UnaryTypeTraitExpr , Expr) STMT(QualifiedDeclRefExpr , DeclRefExpr) STMT(UnresolvedDeclRefExpr , Expr) STMT(CXXDestroyExpr , Expr) +STMT(CXXConstructExpr , Expr) // Obj-C Expressions. STMT(ObjCStringLiteral , Expr) diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 0c9b6270a4..1e96395d46 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -254,6 +254,37 @@ CXXTemporaryObjectExpr::~CXXTemporaryObjectExpr() { delete [] Args; } +CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, VarDecl *VD, + QualType T, CXXConstructorDecl *D, + bool Elidable, + Expr **Args, unsigned NumArgs) { + return new (C) CXXConstructExpr(C, VD, T, D, Elidable, Args, NumArgs); +} + +CXXConstructExpr::CXXConstructExpr(ASTContext &C, VarDecl *vd, + QualType T, CXXConstructorDecl *D, + bool elidable, + Expr **args, unsigned numargs) +: Expr(CXXConstructExprClass, T, + T->isDependentType(), + (T->isDependentType() || + CallExpr::hasAnyValueDependentArguments(args, numargs))), + VD(vd), Constructor(D), Elidable(elidable), Args(0), NumArgs(numargs) { + if (NumArgs > 0) { + Args = new (C) Stmt*[NumArgs]; + for (unsigned i = 0; i < NumArgs; ++i) + Args[i] = args[i]; + } +} + +void CXXConstructExpr::Destroy(ASTContext &C) { + DestroyChildren(C); + if (Args) + C.Deallocate(Args); + this->~CXXConstructExpr(); + C.Deallocate(this); +} + CXXDestroyExpr *CXXDestroyExpr::Create(ASTContext &C, VarDecl *vd) { assert(vd->getKind() == Decl::CXXTempVar || vd->getKind() == Decl::Var && "Can only create a destroy expr with a temp var decl or a var decl!"); @@ -261,6 +292,15 @@ CXXDestroyExpr *CXXDestroyExpr::Create(ASTContext &C, VarDecl *vd) { return new (C) CXXDestroyExpr(vd, C.VoidTy); } +// CXXConstructExpr +Stmt::child_iterator CXXConstructExpr::child_begin() { + return &Args[0]; +} +Stmt::child_iterator CXXConstructExpr::child_end() { + return &Args[0]+NumArgs; +} + +// CXXDestroyExpr Stmt::child_iterator CXXDestroyExpr::child_begin() { return child_iterator(); } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 888c15ad24..5e75a2eb61 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1097,6 +1097,10 @@ void StmtPrinter::VisitUnresolvedFunctionNameExpr(UnresolvedFunctionNameExpr *E) OS << E->getName().getAsString(); } +void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { + // Nothing to print. +} + void StmtPrinter::VisitCXXDestroyExpr(CXXDestroyExpr *E) { // Nothing to print. }