]> granicus.if.org Git - clang/commitdiff
If a ParmVarDecl's default argument is a CXXExprWithTemporaries, return the underlyin...
authorAnders Carlsson <andersca@mac.com>
Tue, 15 Dec 2009 19:16:31 +0000 (19:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 15 Dec 2009 19:16:31 +0000 (19:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91439 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/Sema/SemaExpr.cpp

index ff2b30227860572d8d48b0bedac5cbd3ec73c13a..d226f64b3e95e92bd8a9f3bf843cd72b1409bbf0 100644 (file)
@@ -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<Expr*> (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<ParmVarDecl *>(this)->getDefaultArg();
   }
+  
   void setDefaultArg(Expr *defarg) {
     Init = reinterpret_cast<Stmt *>(defarg);
   }
 
+  unsigned getNumDefaultArgTemporaries() const;
+  CXXTemporary *getDefaultArgTemporary(unsigned i);
+  const CXXTemporary *getDefaultArgTemporary(unsigned i) const {
+    return const_cast<ParmVarDecl *>(this)->getDefaultArgTemporary(i);
+  }
+  
   /// \brief Retrieve the source range that covers the entire default
   /// argument.
   SourceRange getDefaultArgRange() const;  
index 4d0d4225ce73889b7556141beadc228d44d39b82..c0f4b77eeaeecb4d230c4648f1fcad641f4f5d73 100644 (file)
@@ -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<CXXExprWithTemporaries>(Arg))
+    return E->getSubExpr();
+  
+  return Arg;
+}
+
+unsigned ParmVarDecl::getNumDefaultArgTemporaries() const {
+  if (const CXXExprWithTemporaries *E = 
+        dyn_cast<CXXExprWithTemporaries>(getInit()))
+    return E->getNumTemporaries();
+
+  return 0;
+}
+
+CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) {
+  assert(getNumDefaultArgTemporaries() && 
+         "Default arguments does not have any temporaries!");
+
+  CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit());
+  return E->getTemporary(i);
+}
+
 SourceRange ParmVarDecl::getDefaultArgRange() const {
   if (const Expr *E = getInit())
     return E->getSourceRange();
index b95f638e1116348475fd53307dffd7b470e7fe44..cda27cf68716483cbcea63493d690b4401fe2102 100644 (file)
@@ -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<CXXExprWithTemporaries>(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.