When evaluating a VarDecl as a constant or determining whether it is
an integral constant expression, maintain a cache of the value and the
is-an-ICE flag within the VarDecl itself. This eliminates
exponential-time behavior of the Fibonacci template metaprogram.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72428 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 20fe39d..6c62071 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -89,6 +89,15 @@
   return getType();
 }
 
+void VarDecl::setInit(ASTContext &C, Expr *I) { 
+    if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
+      Eval->~EvaluatedStmt();
+      C.Deallocate(Eval);
+    }
+
+    Init = I;
+  }
+
 bool VarDecl::isExternC(ASTContext &Context) const {
   if (!Context.getLangOptions().CPlusPlus)
     return (getDeclContext()->isTranslationUnit() && 
@@ -287,8 +296,13 @@
 
 void VarDecl::Destroy(ASTContext& C) {
   Expr *Init = getInit();
-  if (Init)
+  if (Init) {
     Init->Destroy(C);
+    if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) {
+      Eval->~EvaluatedStmt();
+      C.Deallocate(Eval);
+    }
+  }
   this->~VarDecl();
   C.Deallocate((void *)this);
 }