From 337cba4b3e17b98cfa512dfd12e57f4ccb0859be Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 15 Dec 2009 19:16:31 +0000 Subject: [PATCH] If a ParmVarDecl's default argument is a CXXExprWithTemporaries, return the underlying expr instead. Add getNumDefaultArgTemporaries and getDefaultArgTemporary which returns the temporaries a default arg creates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91439 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Decl.h | 28 ++++++++++------------------ lib/AST/Decl.cpp | 29 +++++++++++++++++++++++++++++ lib/Sema/SemaExpr.cpp | 11 ++--------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index ff2b302278..d226f64b3e 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -21,6 +21,7 @@ #include "clang/AST/ExternalASTSource.h" namespace clang { +class CXXTemporary; class Expr; class FunctionTemplateDecl; class Stmt; @@ -769,14 +770,6 @@ class ParmVarDecl : public VarDecl { /// in, inout, etc. unsigned objcDeclQualifier : 6; - /// \brief Retrieves the fake "value" of an unparsed - static Expr *getUnparsedDefaultArgValue() { - uintptr_t Value = (uintptr_t)-1; - // Mask off the low bits - Value &= ~(uintptr_t)0x07; - return reinterpret_cast (Value); - } - protected: ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, @@ -798,22 +791,21 @@ public: objcDeclQualifier = QTVal; } + Expr *getDefaultArg(); const Expr *getDefaultArg() const { - assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); - assert(!hasUninstantiatedDefaultArg() && - "Default argument is not yet instantiated!"); - return getInit(); - } - Expr *getDefaultArg() { - assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); - assert(!hasUninstantiatedDefaultArg() && - "Default argument is not yet instantiated!"); - return getInit(); + return const_cast(this)->getDefaultArg(); } + void setDefaultArg(Expr *defarg) { Init = reinterpret_cast(defarg); } + unsigned getNumDefaultArgTemporaries() const; + CXXTemporary *getDefaultArgTemporary(unsigned i); + const CXXTemporary *getDefaultArgTemporary(unsigned i) const { + return const_cast(this)->getDefaultArgTemporary(i); + } + /// \brief Retrieve the source range that covers the entire default /// argument. SourceRange getDefaultArgRange() const; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 4d0d4225ce..c0f4b77eea 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -19,6 +19,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/Stmt.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyPrinter.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" @@ -91,6 +92,34 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg); } +Expr *ParmVarDecl::getDefaultArg() { + assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); + assert(!hasUninstantiatedDefaultArg() && + "Default argument is not yet instantiated!"); + + Expr *Arg = getInit(); + if (CXXExprWithTemporaries *E = dyn_cast_or_null(Arg)) + return E->getSubExpr(); + + return Arg; +} + +unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { + if (const CXXExprWithTemporaries *E = + dyn_cast(getInit())) + return E->getNumTemporaries(); + + return 0; +} + +CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) { + assert(getNumDefaultArgTemporaries() && + "Default arguments does not have any temporaries!"); + + CXXExprWithTemporaries *E = cast(getInit()); + return E->getTemporary(i); +} + SourceRange ParmVarDecl::getDefaultArgRange() const { if (const Expr *E = getInit()) return E->getSourceRange(); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b95f638e11..cda27cf687 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3056,18 +3056,11 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, return ExprError(); } - Expr *DefaultExpr = Param->getDefaultArg(); - // If the default expression creates temporaries, we need to // push them to the current stack of expression temporaries so they'll // be properly destroyed. - if (CXXExprWithTemporaries *E - = dyn_cast_or_null(DefaultExpr)) { - assert(!E->shouldDestroyTemporaries() && - "Can't destroy temporaries in a default argument expr!"); - for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I) - ExprTemporaries.push_back(E->getTemporary(I)); - } + for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i) + ExprTemporaries.push_back(Param->getDefaultArgTemporary(i)); } // We already type-checked the argument, so we know it works. -- 2.40.0