Introduce the notion of instantiation dependence into Clang's AST. A
type/expression/template argument/etc. is instantiation-dependent if
it somehow involves a template parameter, even if it doesn't meet the
requirements for the more common kinds of dependence (dependent type,
type-dependent expression, value-dependent expression).

When we see an instantiation-dependent type, we know we always need to
perform substitution into that instantiation-dependent type. This
keeps us from short-circuiting evaluation in places where we
shouldn't, and lets us properly implement C++0x [temp.type]p2.

In theory, this would also allow us to properly mangle
instantiation-dependent-but-not-dependent decltype types per the
Itanium C++ ABI, but we aren't quite there because we still mangle
based on the canonical type in cases like, e.g.,

  template<unsigned> struct A { };
  template<typename T>
    void f(A<sizeof(sizeof(decltype(T() + T())))>) { }
  template void f<int>(A<sizeof(sizeof(int))>);

and therefore get the wrong answer.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134225 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ec064fc..4c42393 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2802,7 +2802,12 @@
 /// on canonical type's (which are always unique).
 QualType ASTContext::getDecltypeType(Expr *e) const {
   DecltypeType *dt;
-  if (e->isTypeDependent()) {
+  
+  // C++0x [temp.type]p2:
+  //   If an expression e involves a template parameter, decltype(e) denotes a
+  //   unique dependent type. Two such decltype-specifiers refer to the same 
+  //   type only if their expressions are equivalent (14.5.6.1). 
+  if (e->isInstantiationDependent()) {
     llvm::FoldingSetNodeID ID;
     DependentDecltypeType::Profile(ID, *this, e);
 
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index cef54e9..72c0e9d 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -533,6 +533,28 @@
   llvm_unreachable("All name kinds handled.");
 }
 
+bool DeclarationNameInfo::isInstantiationDependent() const {
+  switch (Name.getNameKind()) {
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    return false;
+    
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+      return TInfo->getType()->isInstantiationDependentType();
+    
+    return Name.getCXXNameType()->isInstantiationDependentType();
+  }
+  llvm_unreachable("All name kinds handled.");
+}
+
 std::string DeclarationNameInfo::getAsString() const {
   std::string Result;
   llvm::raw_string_ostream OS(Result);
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 1d0319f..3002e30 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -142,9 +142,10 @@
 }
 
 void ExplicitTemplateArgumentList::initializeFrom(
-                                   const TemplateArgumentListInfo &Info,
-                                   bool &Dependent, 
-                                   bool &ContainsUnexpandedParameterPack) {
+                                          const TemplateArgumentListInfo &Info,
+                                                  bool &Dependent, 
+                                                  bool &InstantiationDependent,
+                                       bool &ContainsUnexpandedParameterPack) {
   LAngleLoc = Info.getLAngleLoc();
   RAngleLoc = Info.getRAngleLoc();
   NumTemplateArgs = Info.size();
@@ -152,6 +153,8 @@
   TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
     Dependent = Dependent || Info[i].getArgument().isDependent();
+    InstantiationDependent = InstantiationDependent || 
+                             Info[i].getArgument().isInstantiationDependent();
     ContainsUnexpandedParameterPack 
       = ContainsUnexpandedParameterPack || 
         Info[i].getArgument().containsUnexpandedParameterPack();
@@ -178,14 +181,16 @@
   return sizeFor(Info.size());
 }
 
-/// \brief Compute the type- and value-dependence of a declaration reference
+/// \brief Compute the type-, value-, and instantiation-dependence of a 
+/// declaration reference
 /// based on the declaration being referenced.
 static void computeDeclRefDependence(NamedDecl *D, QualType T,
                                      bool &TypeDependent,
-                                     bool &ValueDependent) {
+                                     bool &ValueDependent,
+                                     bool &InstantiationDependent) {
   TypeDependent = false;
   ValueDependent = false;
-  
+  InstantiationDependent = false;
 
   // (TD) C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -200,20 +205,31 @@
   if (T->isDependentType()) {
     TypeDependent = true;
     ValueDependent = true;
+    InstantiationDependent = true;
     return;
+  } else if (T->isInstantiationDependentType()) {
+    InstantiationDependent = true;
   }
   
   //  (TD)  - a conversion-function-id that specifies a dependent type
   if (D->getDeclName().getNameKind() 
-           == DeclarationName::CXXConversionFunctionName &&
-           D->getDeclName().getCXXNameType()->isDependentType()) {
-    TypeDependent = true;
-    ValueDependent = true;
-    return;
+                                == DeclarationName::CXXConversionFunctionName) {
+    QualType T = D->getDeclName().getCXXNameType();
+    if (T->isDependentType()) {
+      TypeDependent = true;
+      ValueDependent = true;
+      InstantiationDependent = true;
+      return;
+    }
+    
+    if (T->isInstantiationDependentType())
+      InstantiationDependent = true;
   }
+  
   //  (VD)  - the name of a non-type template parameter,
   if (isa<NonTypeTemplateParmDecl>(D)) {
     ValueDependent = true;
+    InstantiationDependent = true;
     return;
   }
   
@@ -223,16 +239,20 @@
     if (Var->getType()->isIntegralOrEnumerationType() &&
         Var->getType().getCVRQualifiers() == Qualifiers::Const) {
       if (const Expr *Init = Var->getAnyInitializer())
-        if (Init->isValueDependent())
+        if (Init->isValueDependent()) {
           ValueDependent = true;
+          InstantiationDependent = true;
+        }
     } 
     
     // (VD) - FIXME: Missing from the standard: 
     //      -  a member function or a static data member of the current 
     //         instantiation
     else if (Var->isStaticDataMember() && 
-             Var->getDeclContext()->isDependentContext())
+             Var->getDeclContext()->isDependentContext()) {
       ValueDependent = true;
+      InstantiationDependent = true;
+    }
     
     return;
   }
@@ -242,6 +262,7 @@
   //         instantiation
   if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
     ValueDependent = true;
+    InstantiationDependent = true;
     return;
   }  
 }
@@ -249,7 +270,9 @@
 void DeclRefExpr::computeDependence() {
   bool TypeDependent = false;
   bool ValueDependent = false;
-  computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent);
+  bool InstantiationDependent = false;
+  computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent,
+                           InstantiationDependent);
   
   // (TD) C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -262,13 +285,16 @@
       hasExplicitTemplateArgs() && 
       TemplateSpecializationType::anyDependentTemplateArguments(
                                                             getTemplateArgs(), 
-                                                       getNumTemplateArgs())) {
+                                                       getNumTemplateArgs(),
+                                                      InstantiationDependent)) {
     TypeDependent = true;
     ValueDependent = true;
+    InstantiationDependent = true;
   }
   
   ExprBits.TypeDependent = TypeDependent;
   ExprBits.ValueDependent = ValueDependent;
+  ExprBits.InstantiationDependent = InstantiationDependent;
   
   // Is the declaration a parameter pack?
   if (getDecl()->isParameterPack())
@@ -280,7 +306,7 @@
                          NamedDecl *FoundD,
                          const TemplateArgumentListInfo *TemplateArgs,
                          QualType T, ExprValueKind VK)
-  : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false),
+  : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
     D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) {
   DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0;
   if (QualifierLoc)
@@ -289,9 +315,17 @@
   if (FoundD)
     getInternalFoundDecl() = FoundD;
   DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0;
-  if (TemplateArgs)
-    getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
-
+  if (TemplateArgs) {
+    bool Dependent = false;
+    bool InstantiationDependent = false;
+    bool ContainsUnexpandedParameterPack = false;
+    getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
+                                             InstantiationDependent,
+                                             ContainsUnexpandedParameterPack);
+    if (InstantiationDependent)
+      setInstantiationDependent(true);
+  }
+      
   computeDependence();
 }
 
@@ -670,6 +704,7 @@
   : Expr(SC, t, VK, OK_Ordinary,
          fn->isTypeDependent(),
          fn->isValueDependent(),
+         fn->isInstantiationDependent(),
          fn->containsUnexpandedParameterPack()),
     NumArgs(numargs) {
 
@@ -680,6 +715,8 @@
       ExprBits.TypeDependent = true;
     if (args[i]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (args[i]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (args[i]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -695,6 +732,7 @@
   : Expr(CallExprClass, t, VK, OK_Ordinary,
          fn->isTypeDependent(),
          fn->isValueDependent(),
+         fn->isInstantiationDependent(),
          fn->containsUnexpandedParameterPack()),
     NumArgs(numargs) {
 
@@ -705,6 +743,8 @@
       ExprBits.TypeDependent = true;
     if (args[i]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (args[i]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (args[i]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -862,6 +902,7 @@
   : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary,
          /*TypeDependent=*/false, 
          /*ValueDependent=*/tsi->getType()->isDependentType(),
+         tsi->getType()->isInstantiationDependentType(),
          tsi->getType()->containsUnexpandedParameterPack()),
     OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), 
     NumComps(numComps), NumExprs(numExprs) 
@@ -917,7 +958,12 @@
     if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) {
       E->setValueDependent(true);
       E->setTypeDependent(true);
-    }
+      E->setInstantiationDependent(true);
+    } 
+    else if (QualifierLoc && 
+             QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) 
+      E->setInstantiationDependent(true);
+    
     E->HasQualifierOrFoundDecl = true;
 
     MemberNameQualifier *NQ = E->getMemberQualifier();
@@ -926,8 +972,15 @@
   }
 
   if (targs) {
+    bool Dependent = false;
+    bool InstantiationDependent = false;
+    bool ContainsUnexpandedParameterPack = false;
     E->HasExplicitTemplateArgumentList = true;
-    E->getExplicitTemplateArgs().initializeFrom(*targs);
+    E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent,
+                                                InstantiationDependent,
+                                              ContainsUnexpandedParameterPack);
+    if (InstantiationDependent)
+      E->setInstantiationDependent(true);
   }
 
   return E;
@@ -1251,7 +1304,7 @@
                            Expr **initExprs, unsigned numInits,
                            SourceLocation rbraceloc)
   : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
-         false),
+         false, false),
     InitExprs(C, numInits),
     LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0),
     HadArrayRangeDesignator(false) 
@@ -1261,6 +1314,8 @@
       ExprBits.TypeDependent = true;
     if (initExprs[I]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (initExprs[I]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (initExprs[I]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
   }
@@ -2575,6 +2630,7 @@
                                  SourceLocation RBracLoc)
   : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary,
          /*TypeDependent=*/false, /*ValueDependent=*/false,
+         /*InstantiationDependent=*/false,
          /*ContainsUnexpandedParameterPack=*/false),
     NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
     HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc),
@@ -2597,7 +2653,8 @@
                                  Expr **Args, unsigned NumArgs,
                                  SourceLocation RBracLoc)
   : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(),
-         T->isDependentType(), T->containsUnexpandedParameterPack()),
+         T->isDependentType(), T->isInstantiationDependentType(),
+         T->containsUnexpandedParameterPack()),
     NumArgs(NumArgs), Kind(Class),
     HasMethod(Method != 0), IsDelegateInitCall(false),
     SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
@@ -2611,6 +2668,8 @@
       ExprBits.TypeDependent = true;
     if (Args[I]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (Args[I]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (Args[I]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
   
@@ -2629,6 +2688,7 @@
                                  SourceLocation RBracLoc)
   : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(),
          Receiver->isTypeDependent(),
+         Receiver->isInstantiationDependent(),
          Receiver->containsUnexpandedParameterPack()),
     NumArgs(NumArgs), Kind(Instance),
     HasMethod(Method != 0), IsDelegateInitCall(false),
@@ -2643,6 +2703,8 @@
       ExprBits.TypeDependent = true;
     if (Args[I]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (Args[I]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (Args[I]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
   
@@ -2784,6 +2846,7 @@
                                      SourceLocation RP) 
    : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary,
           Type->isDependentType(), Type->isDependentType(),
+          Type->isInstantiationDependentType(),
           Type->containsUnexpandedParameterPack()),
      BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) 
 {
@@ -2793,6 +2856,8 @@
       ExprBits.TypeDependent = true;
     if (args[i]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (args[i]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (args[i]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -2822,6 +2887,7 @@
          AssocExprs[ResultIndex]->getObjectKind(),
          AssocExprs[ResultIndex]->isTypeDependent(),
          AssocExprs[ResultIndex]->isValueDependent(),
+         AssocExprs[ResultIndex]->isInstantiationDependent(),
          ContainsUnexpandedParameterPack),
     AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
     SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
@@ -2842,8 +2908,9 @@
          Context.DependentTy,
          VK_RValue,
          OK_Ordinary,
-         /*isTypeDependent=*/  true,
-         /*isValueDependent=*/ true,
+         /*isTypeDependent=*/true,
+         /*isValueDependent=*/true,
+         /*isInstantiationDependent=*/true,
          ContainsUnexpandedParameterPack),
     AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]),
     SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs),
@@ -2877,6 +2944,7 @@
   : Expr(DesignatedInitExprClass, Ty,
          Init->getValueKind(), Init->getObjectKind(),
          Init->isTypeDependent(), Init->isValueDependent(),
+         Init->isInstantiationDependent(),
          Init->containsUnexpandedParameterPack()),
     EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax),
     NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) {
@@ -2897,7 +2965,8 @@
       Expr *Index = IndexExprs[IndexIdx];
       if (Index->isTypeDependent() || Index->isValueDependent())
         ExprBits.ValueDependent = true;
-
+      if (Index->isInstantiationDependent())
+        ExprBits.InstantiationDependent = true;
       // Propagate unexpanded parameter packs.
       if (Index->containsUnexpandedParameterPack())
         ExprBits.ContainsUnexpandedParameterPack = true;
@@ -2909,9 +2978,14 @@
       Expr *Start = IndexExprs[IndexIdx];
       Expr *End = IndexExprs[IndexIdx + 1];
       if (Start->isTypeDependent() || Start->isValueDependent() ||
-          End->isTypeDependent() || End->isValueDependent())
+          End->isTypeDependent() || End->isValueDependent()) {
         ExprBits.ValueDependent = true;
-
+        ExprBits.InstantiationDependent = true;
+      } else if (Start->isInstantiationDependent() || 
+                 End->isInstantiationDependent()) {
+        ExprBits.InstantiationDependent = true;
+      }
+                 
       // Propagate unexpanded parameter packs.
       if (Start->containsUnexpandedParameterPack() ||
           End->containsUnexpandedParameterPack())
@@ -3035,7 +3109,7 @@
                              Expr **exprs, unsigned nexprs,
                              SourceLocation rparenloc, QualType T)
   : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
-         false, false, false),
+         false, false, false, false),
     NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
   assert(!T.isNull() && "ParenListExpr must have a valid type");
   Exprs = new (C) Stmt*[nexprs];
@@ -3044,6 +3118,8 @@
       ExprBits.TypeDependent = true;
     if (exprs[i]->isValueDependent())
       ExprBits.ValueDependent = true;
+    if (exprs[i]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (exprs[i]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -3108,13 +3184,16 @@
 BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
                                    SourceLocation l, bool ByRef, 
                                    bool constAdded)
-  : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false,
+  : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false,
          d->isParameterPack()),
     D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded)
 {
   bool TypeDependent = false;
   bool ValueDependent = false;
-  computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent);
+  bool InstantiationDependent = false;
+  computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent,
+                           InstantiationDependent);
   ExprBits.TypeDependent = TypeDependent;
   ExprBits.ValueDependent = ValueDependent;
+  ExprBits.InstantiationDependent = InstantiationDependent;
 }
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 1a1a0a3..32209f6 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -57,6 +57,7 @@
                        SourceLocation constructorRParen)
   : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
          ty->isDependentType(), ty->isDependentType(),
+         ty->isInstantiationDependentType(),
          ty->containsUnexpandedParameterPack()),
     GlobalNew(globalNew), Initializer(initializer),
     UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
@@ -68,6 +69,9 @@
   AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
   unsigned i = 0;
   if (Array) {
+    if (arraySize->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
+    
     if (arraySize->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -75,6 +79,8 @@
   }
 
   for (unsigned j = 0; j < NumPlacementArgs; ++j) {
+    if (placementArgs[j]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (placementArgs[j]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -82,6 +88,8 @@
   }
 
   for (unsigned j = 0; j < NumConstructorArgs; ++j) {
+    if (constructorArgs[j]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
     if (constructorArgs[j]->containsUnexpandedParameterPack())
       ExprBits.ContainsUnexpandedParameterPack = true;
 
@@ -144,6 +152,14 @@
            (DestroyedType.getTypeSourceInfo() &&
             DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
          /*isValueDependent=*/Base->isValueDependent(),
+         (Base->isInstantiationDependent() ||
+          (QualifierLoc &&
+           QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) ||
+          (ScopeType &&
+           ScopeType->getType()->isInstantiationDependentType()) ||
+          (DestroyedType.getTypeSourceInfo() &&
+           DestroyedType.getTypeSourceInfo()->getType()
+                                             ->isInstantiationDependentType())),
          // ContainsUnexpandedParameterPack
          (Base->containsUnexpandedParameterPack() ||
           (QualifierLoc && 
@@ -212,9 +228,14 @@
                            UnresolvedSetIterator Begin, 
                            UnresolvedSetIterator End,
                            bool KnownDependent,
+                           bool KnownInstantiationDependent,
                            bool KnownContainsUnexpandedParameterPack)
   : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, 
          KnownDependent,
+         (KnownInstantiationDependent ||
+          NameInfo.isInstantiationDependent() ||
+          (QualifierLoc &&
+           QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
          (KnownContainsUnexpandedParameterPack ||
           NameInfo.containsUnexpandedParameterPack() ||
           (QualifierLoc && 
@@ -246,14 +267,18 @@
   // expansions.
   if (TemplateArgs) {
     bool Dependent = false;
+    bool InstantiationDependent = false;
     bool ContainsUnexpandedParameterPack = false;
     getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
+                                             InstantiationDependent,
                                              ContainsUnexpandedParameterPack);
 
     if (Dependent) {
-        ExprBits.TypeDependent = true;
-        ExprBits.ValueDependent = true;
-    } 
+      ExprBits.TypeDependent = true;
+      ExprBits.ValueDependent = true;
+    }
+    if (InstantiationDependent)
+      ExprBits.InstantiationDependent = true;
     if (ContainsUnexpandedParameterPack)
       ExprBits.ContainsUnexpandedParameterPack = true;
   }
@@ -291,6 +316,9 @@
                             const TemplateArgumentListInfo *Args)
   : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary,
          true, true,
+         (NameInfo.isInstantiationDependent() ||
+          (QualifierLoc && 
+           QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
          (NameInfo.containsUnexpandedParameterPack() ||
           (QualifierLoc && 
            QualifierLoc.getNestedNameSpecifier()
@@ -300,11 +328,14 @@
 {
   if (Args) {
     bool Dependent = true;
+    bool InstantiationDependent = true;
     bool ContainsUnexpandedParameterPack
       = ExprBits.ContainsUnexpandedParameterPack;
 
     reinterpret_cast<ExplicitTemplateArgumentList*>(this+1)
-      ->initializeFrom(*Args, Dependent, ContainsUnexpandedParameterPack);
+      ->initializeFrom(*Args, Dependent, InstantiationDependent,
+                       ContainsUnexpandedParameterPack);
+    
     ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
   }
 }
@@ -632,6 +663,7 @@
                                    SourceRange ParenRange)
   : Expr(SC, T, VK_RValue, OK_Ordinary,
          T->isDependentType(), T->isDependentType(),
+         T->isInstantiationDependentType(),
          T->containsUnexpandedParameterPack()),
     Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable),
     ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
@@ -645,6 +677,8 @@
 
       if (args[i]->isValueDependent())
         ExprBits.ValueDependent = true;
+      if (args[i]->isInstantiationDependent())
+        ExprBits.InstantiationDependent = true;
       if (args[i]->containsUnexpandedParameterPack())
         ExprBits.ContainsUnexpandedParameterPack = true;
   
@@ -660,6 +694,7 @@
   : Expr(ExprWithCleanupsClass, subexpr->getType(),
          subexpr->getValueKind(), subexpr->getObjectKind(),
          subexpr->isTypeDependent(), subexpr->isValueDependent(),
+         subexpr->isInstantiationDependent(),
          subexpr->containsUnexpandedParameterPack()),
     SubExpr(subexpr), Temps(0), NumTemps(0) {
   if (numtemps) {
@@ -691,7 +726,7 @@
   : Expr(CXXUnresolvedConstructExprClass, 
          Type->getType().getNonReferenceType(),
          VK_LValue, OK_Ordinary,
-         Type->getType()->isDependentType(), true,
+         Type->getType()->isDependentType(), true, true,
          Type->getType()->containsUnexpandedParameterPack()),
     Type(Type),
     LParenLoc(LParenLoc),
@@ -740,7 +775,7 @@
                                           DeclarationNameInfo MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs)
   : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
-         VK_LValue, OK_Ordinary, true, true,
+         VK_LValue, OK_Ordinary, true, true, true,
          ((Base && Base->containsUnexpandedParameterPack()) ||
           (QualifierLoc && 
            QualifierLoc.getNestedNameSpecifier()
@@ -753,8 +788,10 @@
     MemberNameInfo(MemberNameInfo) {
   if (TemplateArgs) {
     bool Dependent = true;
+    bool InstantiationDependent = true;
     bool ContainsUnexpandedParameterPack = false;
     getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent,
+                                             InstantiationDependent,
                                              ContainsUnexpandedParameterPack);
     if (ContainsUnexpandedParameterPack)
       ExprBits.ContainsUnexpandedParameterPack = true;
@@ -769,7 +806,7 @@
                           NamedDecl *FirstQualifierFoundInScope,
                           DeclarationNameInfo MemberNameInfo)
   : Expr(CXXDependentScopeMemberExprClass, C.DependentTy,
-         VK_LValue, OK_Ordinary, true, true,
+         VK_LValue, OK_Ordinary, true, true, true,
          ((Base && Base->containsUnexpandedParameterPack()) ||
           (QualifierLoc && 
            QualifierLoc.getNestedNameSpecifier()->
@@ -874,6 +911,8 @@
                  // Dependent
                  ((Base && Base->isTypeDependent()) ||
                   BaseType->isDependentType()),
+                 ((Base && Base->isInstantiationDependent()) ||
+                   BaseType->isInstantiationDependentType()),
                  // Contains unexpanded parameter pack
                  ((Base && Base->containsUnexpandedParameterPack()) ||
                   BaseType->containsUnexpandedParameterPack())),
@@ -962,7 +1001,7 @@
                                  SourceLocation NameLoc,
                                  const TemplateArgument &ArgPack)
   : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, 
-         true, false, true),
+         true, true, true, true),
     Param(Param), Arguments(ArgPack.pack_begin()), 
     NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }
 
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 2878dff..f6d4f25 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -174,6 +174,28 @@
   return false;
 }
 
+/// \brief Whether this nested name specifier refers to a dependent
+/// type or not.
+bool NestedNameSpecifier::isInstantiationDependent() const {
+  switch (getKind()) {
+  case Identifier:
+    // Identifier specifiers always represent dependent types
+    return true;
+    
+  case Namespace:
+  case NamespaceAlias:
+  case Global:
+    return false;
+    
+  case TypeSpec:
+  case TypeSpecWithTemplate:
+    return getAsType()->isInstantiationDependentType();
+  }
+  
+  // Necessary to suppress a GCC warning.
+  return false;
+}
+
 bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
   switch (getKind()) {
   case Identifier:
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 103da1d..56c6e7b 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -104,6 +104,45 @@
   return false;
 }
 
+bool TemplateArgument::isInstantiationDependent() const {
+  switch (getKind()) {
+  case Null:
+    assert(false && "Should not have a NULL template argument");
+    return false;
+    
+  case Type:
+    return getAsType()->isInstantiationDependentType();
+    
+  case Template:
+    return getAsTemplate().isInstantiationDependent();
+    
+  case TemplateExpansion:
+    return true;
+    
+  case Declaration:
+    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
+      return DC->isDependentContext();
+    return getAsDecl()->getDeclContext()->isDependentContext();
+    
+  case Integral:
+    // Never dependent
+    return false;
+    
+  case Expression:
+    return getAsExpr()->isInstantiationDependent();
+    
+  case Pack:
+    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
+      if (P->isInstantiationDependent())
+        return true;
+    }
+    
+    return false;
+  }
+  
+  return false;
+}
+
 bool TemplateArgument::isPackExpansion() const {
   switch (getKind()) {
   case Null:
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index b22e4b4..1f7b19a 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -99,6 +99,15 @@
   return true;
 }
 
+bool TemplateName::isInstantiationDependent() const {
+  if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
+    if (QTN->getQualifier()->isInstantiationDependent())
+      return true;
+  }
+  
+  return isDependent();
+}
+
 bool TemplateName::containsUnexpandedParameterPack() const {
   if (TemplateDecl *Template = getAsTemplateDecl()) {
     if (TemplateTemplateParmDecl *TTP 
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 1569173..ca63ec8 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -110,6 +110,7 @@
                                                          Expr *SizeExpr, 
                                                          SourceLocation loc)
     : Type(DependentSizedExtVector, can, /*Dependent=*/true,
+           /*InstantiationDependent=*/true,
            ElementType->isVariablyModifiedType(), 
            (ElementType->containsUnexpandedParameterPack() ||
             (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))),
@@ -129,6 +130,7 @@
 VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
                        VectorKind vecKind)
   : Type(Vector, canonType, vecType->isDependentType(),
+         vecType->isInstantiationDependentType(),
          vecType->isVariablyModifiedType(),
          vecType->containsUnexpandedParameterPack()),
     ElementType(vecType) 
@@ -140,6 +142,7 @@
 VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
                        QualType canonType, VectorKind vecKind)
   : Type(tc, canonType, vecType->isDependentType(),
+         vecType->isInstantiationDependentType(),
          vecType->isVariablyModifiedType(),
          vecType->containsUnexpandedParameterPack()), 
     ElementType(vecType) 
@@ -387,7 +390,7 @@
 ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
                                ObjCProtocolDecl * const *Protocols,
                                unsigned NumProtocols)
-  : Type(ObjCObject, Canonical, false, false, false),
+  : Type(ObjCObject, Canonical, false, false, false, false),
     BaseType(Base) 
 {
   ObjCObjectTypeBits.NumProtocols = NumProtocols;
@@ -1350,7 +1353,7 @@
                          NestedNameSpecifier *NNS, const IdentifierInfo *Name,
                          unsigned NumArgs, const TemplateArgument *Args,
                          QualType Canon)
-  : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true,
+  : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
                     /*VariablyModified=*/false,
                     NNS && NNS->containsUnexpandedParameterPack()),
     NNS(NNS), Name(Name), NumArgs(NumArgs) {
@@ -1485,6 +1488,7 @@
   : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, 
                  epi.RefQualifier, canonical,
                  result->isDependentType(),
+                 result->isInstantiationDependentType(),
                  result->isVariablyModifiedType(),
                  result->containsUnexpandedParameterPack(),
                  epi.ExtInfo),
@@ -1497,7 +1501,9 @@
   for (unsigned i = 0; i != numArgs; ++i) {
     if (args[i]->isDependentType())
       setDependent();
-
+    else if (args[i]->isInstantiationDependentType())
+      setInstantiationDependent();
+    
     if (args[i]->containsUnexpandedParameterPack())
       setContainsUnexpandedParameterPack();
 
@@ -1510,7 +1516,9 @@
     for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) {
       if (epi.Exceptions[i]->isDependentType())
         setDependent();
-
+      else if (epi.Exceptions[i]->isInstantiationDependentType())
+        setInstantiationDependent();
+      
       if (epi.Exceptions[i]->containsUnexpandedParameterPack())
         setContainsUnexpandedParameterPack();
 
@@ -1520,6 +1528,14 @@
     // Store the noexcept expression and context.
     Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + numArgs);
     *noexSlot = epi.NoexceptExpr;
+    
+    if (epi.NoexceptExpr) {
+      if (epi.NoexceptExpr->isValueDependent() 
+          || epi.NoexceptExpr->isTypeDependent())
+        setDependent();
+      else if (epi.NoexceptExpr->isInstantiationDependent())
+        setInstantiationDependent();
+    }
   }
 
   if (epi.ConsumedArguments) {
@@ -1623,6 +1639,7 @@
 
 TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
   : Type(TypeOfExpr, can, E->isTypeDependent(), 
+         E->isInstantiationDependent(),
          E->getType()->isVariablyModifiedType(),
          E->containsUnexpandedParameterPack()), 
     TOExpr(E) {
@@ -1639,6 +1656,7 @@
 
 DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
   : Type(Decltype, can, E->isTypeDependent(), 
+         E->isInstantiationDependent(),
          E->getType()->isVariablyModifiedType(), 
          E->containsUnexpandedParameterPack()), 
     E(E),
@@ -1654,7 +1672,9 @@
 }
 
 TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
-  : Type(TC, can, D->isDependentType(), /*VariablyModified=*/false, 
+  : Type(TC, can, D->isDependentType(), 
+         /*InstantiationDependent=*/D->isDependentType(),
+         /*VariablyModified=*/false, 
          /*ContainsUnexpandedParameterPack=*/false),
     decl(const_cast<TagDecl*>(D)) {}
 
@@ -1674,6 +1694,7 @@
                                        UTTKind UKind,
                                        QualType CanonicalType)
   : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(),
+         UnderlyingType->isInstantiationDependentType(),
          UnderlyingType->isVariablyModifiedType(),
          BaseType->containsUnexpandedParameterPack())
   , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind)
@@ -1707,7 +1728,8 @@
 SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, 
                               QualType Canon,
                               const TemplateArgument &ArgPack)
-  : Type(SubstTemplateTypeParmPack, Canon, true, false, true), Replaced(Param), 
+  : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), 
+    Replaced(Param), 
     Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) 
 { 
 }
@@ -1732,23 +1754,39 @@
 }
 
 bool TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) {
-  return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size());
+anyDependentTemplateArguments(const TemplateArgumentListInfo &Args,
+                              bool &InstantiationDependent) {
+  return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size(),
+                                       InstantiationDependent);
 }
 
 bool TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
-  for (unsigned i = 0; i != N; ++i)
-    if (Args[i].getArgument().isDependent())
+anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N,
+                              bool &InstantiationDependent) {
+  for (unsigned i = 0; i != N; ++i) {
+    if (Args[i].getArgument().isDependent()) {
+      InstantiationDependent = true;
       return true;
+    }
+    
+    if (Args[i].getArgument().isInstantiationDependent())
+      InstantiationDependent = true;
+  }
   return false;
 }
 
 bool TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) {
-  for (unsigned i = 0; i != N; ++i)
-    if (Args[i].isDependent())
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N,
+                              bool &InstantiationDependent) {
+  for (unsigned i = 0; i != N; ++i) {
+    if (Args[i].isDependent()) {
+      InstantiationDependent = true;
       return true;
+    }
+    
+    if (Args[i].isInstantiationDependent())
+      InstantiationDependent = true;
+  }
   return false;
 }
 
@@ -1759,6 +1797,8 @@
   : Type(TemplateSpecialization,
          Canon.isNull()? QualType(this, 0) : Canon,
          Canon.isNull()? T.isDependent() : Canon->isDependentType(),
+         Canon.isNull()? T.isDependent() 
+                       : Canon->isInstantiationDependentType(),
          false, T.containsUnexpandedParameterPack()),
     Template(T), NumArgs(NumArgs) {
   assert(!T.getAsDependentTemplateName() && 
@@ -1767,8 +1807,12 @@
           T.getKind() == TemplateName::SubstTemplateTemplateParm ||
           T.getKind() == TemplateName::SubstTemplateTemplateParmPack) &&
          "Unexpected template name for TemplateSpecializationType");
+  bool InstantiationDependent;
+  (void)InstantiationDependent;
   assert((!Canon.isNull() ||
-          T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
+          T.isDependent() || 
+          anyDependentTemplateArguments(Args, NumArgs, 
+                                        InstantiationDependent)) &&
          "No canonical type for non-dependent class template specialization");
 
   TemplateArgument *TemplateArgs
@@ -1782,6 +1826,9 @@
     // U<T> is always non-dependent, irrespective of the type T.
     if (Canon.isNull() && Args[Arg].isDependent())
       setDependent();
+    else if (Args[Arg].isInstantiationDependent())
+      setInstantiationDependent();
+    
     if (Args[Arg].getKind() == TemplateArgument::Type &&
         Args[Arg].getAsType()->isVariablyModifiedType())
       setVariablyModified();