diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 636 | 
1 files changed, 344 insertions, 292 deletions
| diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 29385e50b8c1..02a05d518251 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -29,14 +29,14 @@ bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,                                                DeclaratorDecl *NewDecl) {    if (!OldDecl->getQualifierLoc())      return false; -   +    NestedNameSpecifierLoc NewQualifierLoc -    = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),  +    = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),                                            TemplateArgs); -   +    if (!NewQualifierLoc)      return true; -   +    NewDecl->setQualifierInfo(NewQualifierLoc);    return false;  } @@ -45,14 +45,14 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,                                                TagDecl *NewDecl) {    if (!OldDecl->getQualifierLoc())      return false; -   +    NestedNameSpecifierLoc NewQualifierLoc -  = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),  +  = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),                                          TemplateArgs); -   +    if (!NewQualifierLoc)      return true; -   +    NewDecl->setQualifierInfo(NewQualifierLoc);    return false;  } @@ -79,7 +79,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,          else {            TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),                                               TemplateArgs, -                                             Aligned->getLocation(),  +                                             Aligned->getLocation(),                                               DeclarationName());            if (Result)              AddAlignedAttr(Aligned->getLocation(), New, Result); @@ -96,8 +96,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,  Decl *  TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) { -  assert(false && "Translation units cannot be instantiated"); -  return D; +  llvm_unreachable("Translation units cannot be instantiated");  }  Decl * @@ -110,8 +109,7 @@ TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {  Decl *  TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) { -  assert(false && "Namespaces cannot be instantiated"); -  return D; +  llvm_unreachable("Namespaces cannot be instantiated");  }  Decl * @@ -165,13 +163,13 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,        newTag->setTypedefNameForAnonDecl(Typedef);      }    } -   +    if (TypedefNameDecl *Prev = D->getPreviousDeclaration()) {      NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,                                                         TemplateArgs);      if (!InstPrev)        return 0; -     +      Typedef->setPreviousDeclaration(cast<TypedefNameDecl>(InstPrev));    } @@ -230,7 +228,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {    if (!PrevAliasTemplate)      Inst->setInstantiatedFromMemberTemplate(D); -   +    Owner->addDecl(Inst);    return Inst; @@ -239,8 +237,6 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {  /// \brief Instantiate an initializer, breaking it into separate  /// initialization arguments.  /// -/// \param S The semantic analysis object. -///  /// \param Init The initializer to instantiate.  ///  /// \param TemplateArgs Template arguments to be substituted into the @@ -249,11 +245,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {  /// \param NewArgs Will be filled in with the instantiation arguments.  ///  /// \returns true if an error occurred, false otherwise -static bool InstantiateInitializer(Sema &S, Expr *Init, +bool Sema::InstantiateInitializer(Expr *Init,                              const MultiLevelTemplateArgumentList &TemplateArgs, -                                   SourceLocation &LParenLoc, -                                   ASTOwningVector<Expr*> &NewArgs, -                                   SourceLocation &RParenLoc) { +                                  SourceLocation &LParenLoc, +                                  ASTOwningVector<Expr*> &NewArgs, +                                  SourceLocation &RParenLoc) {    NewArgs.clear();    LParenLoc = SourceLocation();    RParenLoc = SourceLocation(); @@ -273,24 +269,24 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,    if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {      LParenLoc = ParenList->getLParenLoc();      RParenLoc = ParenList->getRParenLoc(); -    return S.SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), -                        true, TemplateArgs, NewArgs); +    return SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), +                      true, TemplateArgs, NewArgs);    }    if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {      if (!isa<CXXTemporaryObjectExpr>(Construct)) { -      if (S.SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, -                       TemplateArgs, NewArgs)) +      if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, +                     TemplateArgs, NewArgs))          return true;        // FIXME: Fake locations! -      LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart()); +      LParenLoc = PP.getLocForEndOfToken(Init->getLocStart());        RParenLoc = LParenLoc;        return false;      }    } -  -  ExprResult Result = S.SubstExpr(Init, TemplateArgs); + +  ExprResult Result = SubstExpr(Init, TemplateArgs);    if (Result.isInvalid())      return true; @@ -319,7 +315,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {        << D->isStaticDataMember() << DI->getType();      return 0;    } -   +    // Build the instantiated declaration    VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner,                                   D->getInnerLocStart(), @@ -342,21 +338,20 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {      Var->setLexicalDeclContext(D->getLexicalDeclContext());    Var->setAccess(D->getAccess()); -   +    if (!D->isStaticDataMember()) {      Var->setUsed(D->isUsed(false));      Var->setReferenced(D->isReferenced());    } -   +    // FIXME: In theory, we could have a previous declaration for variables that    // are not static data members. -  bool Redeclaration = false;    // FIXME: having to fake up a LookupResult is dumb.    LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(),                          Sema::LookupOrdinaryName, Sema::ForRedeclaration);    if (D->isStaticDataMember())      SemaRef.LookupQualifiedName(Previous, Owner, false); -  SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration); +  SemaRef.CheckVariableDeclaration(Var, Previous);    if (D->isOutOfLine()) {      if (!D->isStaticDataMember()) @@ -368,13 +363,13 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {        SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);    }    SemaRef.InstantiateAttrs(TemplateArgs, D, Var); -   +    // Link instantiations of static data members back to the template from    // which they were instantiated.    if (Var->isStaticDataMember()) -    SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D,  +    SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D,                                                       TSK_ImplicitInstantiation); -   +    if (Var->getAnyInitializer()) {      // We already have an initializer in the class.    } else if (D->getInit()) { @@ -386,8 +381,8 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {      // Instantiate the initializer.      SourceLocation LParenLoc, RParenLoc;      ASTOwningVector<Expr*> InitArgs(SemaRef); -    if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc, -                                InitArgs, RParenLoc)) { +    if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc, +                                        InitArgs, RParenLoc)) {        bool TypeMayContainAuto = true;        // Attach the initializer to the declaration, if we have one.        if (InitArgs.size() == 0) @@ -409,7 +404,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {        // because of a bogus initializer.        Var->setInvalidDecl();      } -     +      SemaRef.PopExpressionEvaluationContext();    } else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) &&               !Var->isCXXForRangeDecl()) @@ -489,14 +484,14 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {    }    SemaRef.InstantiateAttrs(TemplateArgs, D, Field); -   +    if (Invalid)      Field->setInvalidDecl();    if (!Field->getDeclName()) {      // Keep track of where this decl came from.      SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D); -  }  +  }    if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {      if (Parent->isAnonymousStructOrUnion() &&          Parent->getRedeclContext()->isFunctionOrMethod()) @@ -518,11 +513,11 @@ Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {    for (IndirectFieldDecl::chain_iterator PI =         D->chain_begin(), PE = D->chain_end();         PI != PE; ++PI) { -    NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI,  +    NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI,                                                TemplateArgs);      if (!Next)        return 0; -     +      NamedChain[i++] = Next;    } @@ -560,13 +555,13 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {      FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getFriendLoc(), InstTy);      if (!FD)        return 0; -     +      FD->setAccess(AS_public);      FD->setUnsupportedFriend(D->isUnsupportedFriend());      Owner->addDecl(FD);      return FD; -  }  -   +  } +    NamedDecl *ND = D->getFriendDecl();    assert(ND && "friend decl must be a decl or a type!"); @@ -578,7 +573,7 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {    if (!NewND) return 0;    FriendDecl *FD = -    FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),  +    FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),                         cast<NamedDecl>(NewND), D->getFriendLoc());    FD->setAccess(AS_public);    FD->setUnsupportedFriend(D->isUnsupportedFriend()); @@ -620,7 +615,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {                                                         TemplateArgs,                                                         UnderlyingLoc,                                                         DeclarationName())); -       +        if (!Enum->getIntegerTypeSourceInfo())          Enum->setIntegerType(SemaRef.Context.IntTy);      } @@ -641,8 +636,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {    if (D->getDeclContext()->isFunctionOrMethod())      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); -     -  llvm::SmallVector<Decl*, 4> Enumerators; + +  SmallVector<Decl*, 4> Enumerators;    EnumConstantDecl *LastEnumConst = 0;    for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(), @@ -683,7 +678,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {        Enum->addDecl(EnumConst);        Enumerators.push_back(EnumConst);        LastEnumConst = EnumConst; -       +        if (D->getDeclContext()->isFunctionOrMethod()) {          // If the enumeration is within a function or method, record the enum          // constant as a local. @@ -703,8 +698,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {  }  Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { -  assert(false && "EnumConstantDecls can only occur within EnumDecls."); -  return 0; +  llvm_unreachable("EnumConstantDecls can only occur within EnumDecls.");  }  Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { @@ -789,7 +783,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {        // template parameters of the original declaration. In this one        // case, we don't complain about the ill-formed friend        // declaration. -      if (isFriend && Pattern->getIdentifier() &&  +      if (isFriend && Pattern->getIdentifier() &&            Pattern->getIdentifier()->isStr("_Map_base") &&            DC->isNamespace() &&            cast<NamespaceDecl>(DC)->getIdentifier() && @@ -812,7 +806,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {        // Make sure the parameter lists match.        if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams, -                                                  Complain,  +                                                  Complain,                                                    Sema::TPL_TemplateMatch)) {          if (Complain)            return 0; @@ -859,7 +853,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {      if (!PrevClassTemplate)        Inst->setInstantiatedFromMemberTemplate(D);    } -   +    // Trigger creation of the type for the instantiation.    SemaRef.Context.getInjectedClassNameType(RecordInst,                                      Inst->getInjectedClassNameSpecialization()); @@ -869,14 +863,14 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {      DC->makeDeclVisibleInContext(Inst, /*Recoverable*/ false);      return Inst;    } -   +    Owner->addDecl(Inst);    if (!PrevClassTemplate) {      // Queue up any out-of-line partial specializations of this member      // class template; the client will force their instantiation once      // the enclosing class has been instantiated. -    llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; +    SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;      D->getPartialSpecializations(PartialSpecs);      for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)        if (PartialSpecs[I]->isOutOfLine()) @@ -890,19 +884,19 @@ Decl *  TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(                                     ClassTemplatePartialSpecializationDecl *D) {    ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate(); -   +    // Lookup the already-instantiated declaration in the instantiation    // of the class template and return that.    DeclContext::lookup_result Found      = Owner->lookup(ClassTemplate->getDeclName());    if (Found.first == Found.second)      return 0; -   +    ClassTemplateDecl *InstClassTemplate      = dyn_cast<ClassTemplateDecl>(*Found.first);    if (!InstClassTemplate)      return 0; -   +    if (ClassTemplatePartialSpecializationDecl *Result          = InstClassTemplate->findPartialSpecInstantiatedFromMember(D))      return Result; @@ -914,7 +908,7 @@ Decl *  TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    // Create a local instantiation scope for this function template, which    // will contain the instantiations of the template parameters and then get -  // merged with the local instantiation scope for the function template  +  // merged with the local instantiation scope for the function template    // itself.    LocalInstantiationScope Scope(SemaRef); @@ -922,16 +916,16 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    TemplateParameterList *InstParams = SubstTemplateParams(TempParams);    if (!InstParams)      return NULL; -   +    FunctionDecl *Instantiated = 0;    if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) -    Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod,  +    Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod,                                                                   InstParams));    else      Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl( -                                                          D->getTemplatedDecl(),  +                                                          D->getTemplatedDecl(),                                                                  InstParams)); -   +    if (!Instantiated)      return 0; @@ -939,10 +933,10 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    // Link the instantiated function template declaration to the function    // template from which it was instantiated. -  FunctionTemplateDecl *InstTemplate  +  FunctionTemplateDecl *InstTemplate      = Instantiated->getDescribedFunctionTemplate();    InstTemplate->setAccess(D->getAccess()); -  assert(InstTemplate &&  +  assert(InstTemplate &&           "VisitFunctionDecl/CXXMethodDecl didn't create a template!");    bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None); @@ -952,7 +946,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {    if (!InstTemplate->getInstantiatedFromMemberTemplate() &&        !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))      InstTemplate->setInstantiatedFromMemberTemplate(D); -   +    // Make declarations visible in the appropriate context.    if (!isFriend)      Owner->addDecl(InstTemplate); @@ -1018,7 +1012,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,    FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();    void *InsertPos = 0;    if (FunctionTemplate && !TemplateParams) { -    std::pair<const TemplateArgument *, unsigned> Innermost  +    std::pair<const TemplateArgument *, unsigned> Innermost        = TemplateArgs.getInnermost();      FunctionDecl *SpecFunc @@ -1038,11 +1032,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,    bool MergeWithParentScope = (TemplateParams != 0) ||      Owner->isFunctionOrMethod() || -    !(isa<Decl>(Owner) &&  +    !(isa<Decl>(Owner) &&        cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());    LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); -  llvm::SmallVector<ParmVarDecl *, 4> Params; +  SmallVector<ParmVarDecl *, 4> Params;    TypeSourceInfo *TInfo = D->getTypeSourceInfo();    TInfo = SubstFunctionType(D, Params);    if (!TInfo) @@ -1068,7 +1062,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,      DC = SemaRef.computeDeclContext(SS);      if (!DC) return 0;    } else { -    DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),  +    DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),                                           TemplateArgs);    } @@ -1076,7 +1070,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,        FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),                             D->getLocation(), D->getDeclName(), T, TInfo,                             D->getStorageClass(), D->getStorageClassAsWritten(), -                           D->isInlineSpecified(), D->hasWrittenPrototype()); +                           D->isInlineSpecified(), D->hasWrittenPrototype(), +                           /*isConstexpr*/ false);    if (QualifierLoc)      Function->setQualifierInfo(QualifierLoc); @@ -1110,7 +1105,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,        Params.push_back(Param);      }    } -  Function->setParams(Params.data(), Params.size()); +  Function->setParams(Params);    SourceLocation InstantiateAtPOI;    if (TemplateParams) { @@ -1124,7 +1119,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,      //      //   X<int> x;      // -    // We are instantiating the friend function template "f" within X<int>,  +    // We are instantiating the friend function template "f" within X<int>,      // which means substituting int for T, but leaving "f" as a friend function      // template.      // Build the function template itself. @@ -1144,25 +1139,28 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,      }    } else if (FunctionTemplate) {      // Record this function template specialization. -    std::pair<const TemplateArgument *, unsigned> Innermost  +    std::pair<const TemplateArgument *, unsigned> Innermost        = TemplateArgs.getInnermost();      Function->setFunctionTemplateSpecialization(FunctionTemplate,                              TemplateArgumentList::CreateCopy(SemaRef.Context,                                                               Innermost.first,                                                               Innermost.second),                                                  InsertPos); -  } else if (isFriend && D->isThisDeclarationADefinition()) { -    // TODO: should we remember this connection regardless of whether -    // the friend declaration provided a body? +  } else if (isFriend) { +    // Note, we need this connection even if the friend doesn't have a body. +    // Its body may exist but not have been attached yet due to deferred +    // parsing. +    // FIXME: It might be cleaner to set this when attaching the body to the +    // friend function declaration, however that would require finding all the +    // instantiations and modifying them.      Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);    } -     +    if (InitFunctionInstantiation(Function, D))      Function->setInvalidDecl(); -  bool Redeclaration = false;    bool isExplicitSpecialization = false; -     +    LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),                          Sema::LookupOrdinaryName, Sema::ForRedeclaration); @@ -1194,15 +1192,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,                                                      &ExplicitArgs,                                                      Previous))        Function->setInvalidDecl(); -                                           +      isExplicitSpecialization = true;    } else if (TemplateParams || !FunctionTemplate) { -    // Look only into the namespace where the friend would be declared to  -    // find a previous declaration. This is the innermost enclosing namespace,  +    // Look only into the namespace where the friend would be declared to +    // find a previous declaration. This is the innermost enclosing namespace,      // as described in ActOnFriendFunctionDecl.      SemaRef.LookupQualifiedName(Previous, DC); -     +      // In C++, the previous declaration we find might be a tag type      // (class or enum). In this case, the new declaration will hide the      // tag type. Note that this does does not apply if we're declaring a @@ -1210,9 +1208,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,      if (Previous.isSingleTagDecl())        Previous.clear();    } -   +    SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous, -                                   isExplicitSpecialization, Redeclaration); +                                   isExplicitSpecialization);    NamedDecl *PrincipalDecl = (TemplateParams                                ? cast<NamedDecl>(FunctionTemplate) @@ -1238,11 +1236,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,        const FunctionDecl *Definition = 0;        if (Function->isDefined(Definition) &&            Definition->getTemplateSpecializationKind() == TSK_Undeclared) { -        SemaRef.Diag(Function->getLocation(), diag::err_redefinition)  +        SemaRef.Diag(Function->getLocation(), diag::err_redefinition)            << Function->getDeclName();          SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); -        Function->setInvalidDecl();         -      }  +        Function->setInvalidDecl(); +      }        // Check for redefinitions due to other instantiations of this or        // a similar friend function.        else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(), @@ -1269,7 +1267,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,            if (const FunctionDecl *RPattern                = R->getTemplateInstantiationPattern())              if (RPattern->isDefined(RPattern)) { -              SemaRef.Diag(Function->getLocation(), diag::err_redefinition)  +              SemaRef.Diag(Function->getLocation(), diag::err_redefinition)                  << Function->getDeclName();                SemaRef.Diag(R->getLocation(), diag::note_previous_definition);                Function->setInvalidDecl(); @@ -1290,14 +1288,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,  Decl *  TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, -                                      TemplateParameterList *TemplateParams) { +                                      TemplateParameterList *TemplateParams, +                                      bool IsClassScopeSpecialization) {    FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();    void *InsertPos = 0;    if (FunctionTemplate && !TemplateParams) {      // We are creating a function template specialization from a function      // template. Check whether there is already a function template      // specialization for this particular set of template arguments. -    std::pair<const TemplateArgument *, unsigned> Innermost  +    std::pair<const TemplateArgument *, unsigned> Innermost        = TemplateArgs.getInnermost();      FunctionDecl *SpecFunc @@ -1316,12 +1315,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,      isFriend = (D->getFriendObjectKind() != Decl::FOK_None);    bool MergeWithParentScope = (TemplateParams != 0) || -    !(isa<Decl>(Owner) &&  +    !(isa<Decl>(Owner) &&        cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());    LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);    // Instantiate enclosing template arguments for friends. -  llvm::SmallVector<TemplateParameterList *, 4> TempParamLists; +  SmallVector<TemplateParameterList *, 4> TempParamLists;    unsigned NumTempParamLists = 0;    if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) {      TempParamLists.set_size(NumTempParamLists); @@ -1334,7 +1333,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,      }    } -  llvm::SmallVector<ParmVarDecl *, 4> Params; +  SmallVector<ParmVarDecl *, 4> Params;    TypeSourceInfo *TInfo = D->getTypeSourceInfo();    TInfo = SubstFunctionType(D, Params);    if (!TInfo) @@ -1352,18 +1351,18 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,    // synthesized in the method declaration.    if (!isa<FunctionProtoType>(T.IgnoreParens())) {      assert(!Params.size() && "Instantiating type could not yield parameters"); -    llvm::SmallVector<QualType, 4> ParamTypes; -    if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(),  -                               D->getNumParams(), TemplateArgs, ParamTypes,  +    SmallVector<QualType, 4> ParamTypes; +    if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), +                               D->getNumParams(), TemplateArgs, ParamTypes,                                 &Params)) -      return 0;     +      return 0;    }    NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();    if (QualifierLoc) {      QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,                                                   TemplateArgs); -    if (!QualifierLoc)  +    if (!QualifierLoc)        return 0;    } @@ -1396,7 +1395,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,                                          StartLoc, NameInfo, T, TInfo,                                          Constructor->isExplicit(),                                          Constructor->isInlineSpecified(), -                                        false); +                                        false, /*isConstexpr*/ false);    } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {      Method = CXXDestructorDecl::Create(SemaRef.Context, Record,                                         StartLoc, NameInfo, T, TInfo, @@ -1407,6 +1406,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,                                         StartLoc, NameInfo, T, TInfo,                                         Conversion->isInlineSpecified(),                                         Conversion->isExplicit(), +                                       /*isConstexpr*/ false,                                         Conversion->getLocEnd());    } else {      Method = CXXMethodDecl::Create(SemaRef.Context, Record, @@ -1414,7 +1414,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,                                     D->isStatic(),                                     D->getStorageClassAsWritten(),                                     D->isInlineSpecified(), -                                   D->getLocEnd()); +                                   /*isConstexpr*/ false, D->getLocEnd());    }    if (QualifierLoc) @@ -1446,7 +1446,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,      Method->setDescribedFunctionTemplate(FunctionTemplate);    } else if (FunctionTemplate) {      // Record this function template specialization. -    std::pair<const TemplateArgument *, unsigned> Innermost  +    std::pair<const TemplateArgument *, unsigned> Innermost        = TemplateArgs.getInnermost();      Method->setFunctionTemplateSpecialization(FunctionTemplate,                           TemplateArgumentList::CreateCopy(SemaRef.Context, @@ -1457,7 +1457,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,      // Record that this is an instantiation of a member function.      Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);    } -   +    // If we are instantiating a member function defined    // out-of-line, the instantiation will have the same lexical    // context (which will be a namespace scope) as the template. @@ -1475,7 +1475,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,    // Attach the parameters    for (unsigned P = 0; P < Params.size(); ++P)      Params[P]->setOwningFunction(Method); -  Method->setParams(Params.data(), Params.size()); +  Method->setParams(Params);    if (InitMethodInstantiation(Method, D))      Method->setInvalidDecl(); @@ -1494,8 +1494,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,        Previous.clear();    } -  bool Redeclaration = false; -  SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration); +  if (!IsClassScopeSpecialization) +    SemaRef.CheckFunctionDeclaration(0, Method, Previous, false);    if (D->isPure())      SemaRef.CheckPureMethod(Method, SourceRange()); @@ -1514,7 +1514,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,                              : Method);      if (isFriend)        Record->makeDeclVisibleInContext(DeclToAdd); -    else +    else if (!IsClassScopeSpecialization)        Owner->addDecl(DeclToAdd);    } @@ -1558,14 +1558,14 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(                                   D->wasDeclaredWithTypename(),                                   D->isParameterPack());    Inst->setAccess(AS_public); -   +    if (D->hasDefaultArgument()) -    Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false);   +    Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false); -  // Introduce this template parameter's instantiation into the instantiation  +  // Introduce this template parameter's instantiation into the instantiation    // scope.    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst); -   +    return Inst;  } @@ -1573,26 +1573,26 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(                                                   NonTypeTemplateParmDecl *D) {    // Substitute into the type of the non-type template parameter.    TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc(); -  llvm::SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; -  llvm::SmallVector<QualType, 4> ExpandedParameterPackTypes; +  SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; +  SmallVector<QualType, 4> ExpandedParameterPackTypes;    bool IsExpandedParameterPack = false; -  TypeSourceInfo *DI;   +  TypeSourceInfo *DI;    QualType T;    bool Invalid = false;    if (D->isExpandedParameterPack()) { -    // The non-type template parameter pack is an already-expanded pack  +    // The non-type template parameter pack is an already-expanded pack      // expansion of types. Substitute into each of the expanded types.      ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes());      ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes());      for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {        TypeSourceInfo *NewDI =SemaRef.SubstType(D->getExpansionTypeSourceInfo(I),                                                 TemplateArgs, -                                               D->getLocation(),  +                                               D->getLocation(),                                                 D->getDeclName());        if (!NewDI)          return 0; -       +        ExpandedParameterPackTypesAsWritten.push_back(NewDI);        QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(),                                                                D->getLocation()); @@ -1600,7 +1600,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(          return 0;        ExpandedParameterPackTypes.push_back(NewT);      } -     +      IsExpandedParameterPack = true;      DI = D->getTypeSourceInfo();      T = DI->getType(); @@ -1610,9 +1610,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(      // types.      PackExpansionTypeLoc Expansion = cast<PackExpansionTypeLoc>(TL);      TypeLoc Pattern = Expansion.getPatternLoc(); -    llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; +    SmallVector<UnexpandedParameterPack, 2> Unexpanded;      SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); -     +      // Determine whether the set of unexpanded parameter packs can and should      // be expanded.      bool Expand = true; @@ -1622,22 +1622,21 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(      llvm::Optional<unsigned> NumExpansions = OrigNumExpansions;      if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(),                                                  Pattern.getSourceRange(), -                                                Unexpanded.data(), -                                                Unexpanded.size(), +                                                Unexpanded,                                                  TemplateArgs, -                                                Expand, RetainExpansion,  +                                                Expand, RetainExpansion,                                                  NumExpansions))        return 0; -     +      if (Expand) {        for (unsigned I = 0; I != *NumExpansions; ++I) {          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);          TypeSourceInfo *NewDI = SemaRef.SubstType(Pattern, TemplateArgs, -                                                  D->getLocation(),  +                                                  D->getLocation(),                                                    D->getDeclName());          if (!NewDI)            return 0; -         +          ExpandedParameterPackTypesAsWritten.push_back(NewDI);          QualType NewT = SemaRef.CheckNonTypeTemplateParameterType(                                                                NewDI->getType(), @@ -1646,7 +1645,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(            return 0;          ExpandedParameterPackTypes.push_back(NewT);        } -       +        // Note that we have an expanded parameter pack. The "type" of this        // expanded parameter pack is the original expansion type, but callers        // will end up using the expanded parameter pack types for type-checking. @@ -1658,62 +1657,62 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(        // pattern and create a new pack expansion type.        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);        TypeSourceInfo *NewPattern = SemaRef.SubstType(Pattern, TemplateArgs, -                                                     D->getLocation(),  +                                                     D->getLocation(),                                                       D->getDeclName());        if (!NewPattern)          return 0; -       +        DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(),                                        NumExpansions);        if (!DI)          return 0; -       +        T = DI->getType();      }    } else {      // Simple case: substitution into a parameter that is not a parameter pack. -    DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,  +    DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,                             D->getLocation(), D->getDeclName());      if (!DI)        return 0; -     +      // Check that this type is acceptable for a non-type template parameter. -    T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(),  +    T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(),                                                    D->getLocation());      if (T.isNull()) {        T = SemaRef.Context.IntTy;        Invalid = true;      }    } -   +    NonTypeTemplateParmDecl *Param;    if (IsExpandedParameterPack) -    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,  +    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,                                              D->getInnerLocStart(),                                              D->getLocation(), -                                    D->getDepth() - TemplateArgs.getNumLevels(),  -                                            D->getPosition(),  +                                    D->getDepth() - TemplateArgs.getNumLevels(), +                                            D->getPosition(),                                              D->getIdentifier(), T,                                              DI,                                              ExpandedParameterPackTypes.data(),                                              ExpandedParameterPackTypes.size(),                                      ExpandedParameterPackTypesAsWritten.data());    else -    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,  +    Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,                                              D->getInnerLocStart(),                                              D->getLocation(), -                                    D->getDepth() - TemplateArgs.getNumLevels(),  -                                            D->getPosition(),  -                                            D->getIdentifier(), T,  +                                    D->getDepth() - TemplateArgs.getNumLevels(), +                                            D->getPosition(), +                                            D->getIdentifier(), T,                                              D->isParameterPack(), DI); -   +    Param->setAccess(AS_public);    if (Invalid)      Param->setInvalidDecl(); -   +    Param->setDefaultArgument(D->getDefaultArgument(), false); -   -  // Introduce this template parameter's instantiation into the instantiation  + +  // Introduce this template parameter's instantiation into the instantiation    // scope.    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);    return Param; @@ -1732,34 +1731,34 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(      InstParams = SubstTemplateParams(TempParams);      if (!InstParams)        return NULL; -  }   -   +  } +    // Build the template template parameter.    TemplateTemplateParmDecl *Param      = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(), -                                   D->getDepth() - TemplateArgs.getNumLevels(),  -                                       D->getPosition(), D->isParameterPack(),  +                                   D->getDepth() - TemplateArgs.getNumLevels(), +                                       D->getPosition(), D->isParameterPack(),                                         D->getIdentifier(), InstParams);    Param->setDefaultArgument(D->getDefaultArgument(), false);    Param->setAccess(AS_public); -   -  // Introduce this template parameter's instantiation into the instantiation  + +  // Introduce this template parameter's instantiation into the instantiation    // scope.    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); -   +    return Param;  }  Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {    // Using directives are never dependent (and never contain any types or    // expressions), so they require no explicit instantiation work. -   +    UsingDirectiveDecl *Inst      = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(), -                                 D->getNamespaceKeyLocation(),  +                                 D->getNamespaceKeyLocation(),                                   D->getQualifierLoc(), -                                 D->getIdentLocation(),  -                                 D->getNominatedNamespace(),  +                                 D->getIdentLocation(), +                                 D->getNominatedNamespace(),                                   D->getCommonAncestor());    Owner->addDecl(Inst);    return Inst; @@ -1863,7 +1862,7 @@ Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {  Decl * TemplateDeclInstantiator      ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {    NestedNameSpecifierLoc QualifierLoc -    = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),  +    = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),                                            TemplateArgs);    if (!QualifierLoc)      return 0; @@ -1891,7 +1890,7 @@ Decl * TemplateDeclInstantiator        = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs);    if (!QualifierLoc)      return 0; -   +    CXXScopeSpec SS;    SS.Adopt(QualifierLoc); @@ -1909,6 +1908,29 @@ Decl * TemplateDeclInstantiator    return UD;  } + +Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( +                                     ClassScopeFunctionSpecializationDecl *Decl) { +  CXXMethodDecl *OldFD = Decl->getSpecialization(); +  CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, 0, true)); + +  LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, +                        Sema::ForRedeclaration); + +  SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext); +  if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous)) { +    NewFD->setInvalidDecl(); +    return NewFD; +  } + +  // Associate the specialization with the pattern. +  FunctionDecl *Specialization = cast<FunctionDecl>(Previous.getFoundDecl()); +  assert(Specialization && "Class scope Specialization is null"); +  SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD); + +  return NewFD; +} +  Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,                        const MultiLevelTemplateArgumentList &TemplateArgs) {    TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); @@ -1930,7 +1952,7 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {    bool Invalid = false;    unsigned N = L->size(); -  typedef llvm::SmallVector<NamedDecl *, 8> ParamVector; +  typedef SmallVector<NamedDecl *, 8> ParamVector;    ParamVector Params;    Params.reserve(N);    for (TemplateParameterList::iterator PI = L->begin(), PE = L->end(); @@ -1951,13 +1973,13 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {    return InstL;  } -/// \brief Instantiate the declaration of a class template partial  +/// \brief Instantiate the declaration of a class template partial  /// specialization.  ///  /// \param ClassTemplate the (instantiated) class template that is partially  // specialized by the instantiation of \p PartialSpec.  /// -/// \param PartialSpec the (uninstantiated) class template partial  +/// \param PartialSpec the (uninstantiated) class template partial  /// specialization that we are instantiating.  ///  /// \returns The instantiated partial specialization, if successful; otherwise, @@ -1970,28 +1992,28 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(    // specialization, which will contain the instantiations of the template    // parameters.    LocalInstantiationScope Scope(SemaRef); -   +    // Substitute into the template parameters of the class template partial    // specialization.    TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();    TemplateParameterList *InstParams = SubstTemplateParams(TempParams);    if (!InstParams)      return 0; -   +    // Substitute into the template arguments of the class template partial    // specialization.    TemplateArgumentListInfo InstTemplateArgs; // no angle locations -  if (SemaRef.Subst(PartialSpec->getTemplateArgsAsWritten(),  -                    PartialSpec->getNumTemplateArgsAsWritten(),  +  if (SemaRef.Subst(PartialSpec->getTemplateArgsAsWritten(), +                    PartialSpec->getNumTemplateArgsAsWritten(),                      InstTemplateArgs, TemplateArgs))      return 0; -   +    // Check that the template argument list is well-formed for this    // class template. -  llvm::SmallVector<TemplateArgument, 4> Converted; -  if (SemaRef.CheckTemplateArgumentList(ClassTemplate,  +  SmallVector<TemplateArgument, 4> Converted; +  if (SemaRef.CheckTemplateArgumentList(ClassTemplate,                                          PartialSpec->getLocation(), -                                        InstTemplateArgs,  +                                        InstTemplateArgs,                                          false,                                          Converted))      return 0; @@ -2002,10 +2024,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(    ClassTemplateSpecializationDecl *PrevDecl      = ClassTemplate->findPartialSpecialization(Converted.data(),                                                 Converted.size(), InsertPos); -   +    // Build the canonical type that describes the converted template    // arguments of the class template partial specialization. -  QualType CanonType  +  QualType CanonType      = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),                                                      Converted.data(),                                                      Converted.size()); @@ -2023,7 +2045,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(                                                      PartialSpec->getLocation(),                                                      InstTemplateArgs,                                                      CanonType); -   +    if (PrevDecl) {      // We've already seen a partial specialization with the same template      // parameters and template arguments. This can happen, for example, when @@ -2046,17 +2068,17 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(        << SemaRef.Context.getTypeDeclType(PrevDecl);      return 0;    } -   -   + +    // Create the class template partial specialization declaration.    ClassTemplatePartialSpecializationDecl *InstPartialSpec -    = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context,  +    = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context,                                                       PartialSpec->getTagKind(), -                                                     Owner,  +                                                     Owner,                                                       PartialSpec->getLocStart(),                                                       PartialSpec->getLocation(),                                                       InstParams, -                                                     ClassTemplate,  +                                                     ClassTemplate,                                                       Converted.data(),                                                       Converted.size(),                                                       InstTemplateArgs, @@ -2069,7 +2091,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(    InstPartialSpec->setInstantiatedFromMember(PartialSpec);    InstPartialSpec->setTypeAsWritten(WrittenTy); -   +    // Add this partial specialization to the set of class template partial    // specializations.    ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos); @@ -2078,7 +2100,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(  TypeSourceInfo*  TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, -                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) { +                              SmallVectorImpl<ParmVarDecl *> &Params) {    TypeSourceInfo *OldTInfo = D->getTypeSourceInfo();    assert(OldTInfo && "substituting function without type source info");    assert(Params.empty() && "parameter vector is non-empty at start"); @@ -2104,7 +2126,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,          if (!OldParam->isParameterPack() ||              (NewIdx < NumNewParams &&               NewProtoLoc->getArg(NewIdx)->isParameterPack())) { -          // Simple case: normal parameter, or a parameter pack that's  +          // Simple case: normal parameter, or a parameter pack that's            // instantiated to a (still-dependent) parameter pack.            ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++);            Params.push_back(NewParam); @@ -2112,7 +2134,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,                                                                 NewParam);            continue;          } -         +          // Parameter pack: make the instantiation an argument pack.          SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(                                                                        OldParam); @@ -2184,43 +2206,42 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,    if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) {      // The function has an exception specification or a "noreturn"      // attribute. Substitute into each of the exception types. -    llvm::SmallVector<QualType, 4> Exceptions; +    SmallVector<QualType, 4> Exceptions;      for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) {        // FIXME: Poor location information!        if (const PackExpansionType *PackExpansion              = Proto->getExceptionType(I)->getAs<PackExpansionType>()) {          // We have a pack expansion. Instantiate it. -        llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; +        SmallVector<UnexpandedParameterPack, 2> Unexpanded;          SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),                                                  Unexpanded); -        assert(!Unexpanded.empty() &&  +        assert(!Unexpanded.empty() &&                 "Pack expansion without parameter packs?");          bool Expand = false;          bool RetainExpansion = false;          llvm::Optional<unsigned> NumExpansions                                            = PackExpansion->getNumExpansions(); -        if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),  +        if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),                                                      SourceRange(), -                                                    Unexpanded.data(),  -                                                    Unexpanded.size(), +                                                    Unexpanded,                                                      TemplateArgs, -                                                    Expand,  +                                                    Expand,                                                      RetainExpansion,                                                      NumExpansions))            break;          if (!Expand) {            // We can't expand this pack expansion into separate arguments yet; -          // just substitute into the pattern and create a new pack expansion  +          // just substitute into the pattern and create a new pack expansion            // type.            Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); -          QualType T = SemaRef.SubstType(PackExpansion->getPattern(),  +          QualType T = SemaRef.SubstType(PackExpansion->getPattern(),                                           TemplateArgs,                                         New->getLocation(), New->getDeclName());            if (T.isNull())              break; -           +            T = SemaRef.Context.getPackExpansionType(T, NumExpansions);            Exceptions.push_back(T);            continue; @@ -2230,8 +2251,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,          bool Invalid = false;          for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {            Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); -           -          QualType T = SemaRef.SubstType(PackExpansion->getPattern(),  + +          QualType T = SemaRef.SubstType(PackExpansion->getPattern(),                                           TemplateArgs,                                         New->getLocation(), New->getDeclName());            if (T.isNull()) { @@ -2247,11 +2268,11 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,          continue;        } -       +        QualType T          = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs,                              New->getLocation(), New->getDeclName()); -      if (T.isNull() ||  +      if (T.isNull() ||            SemaRef.CheckSpecifiedExceptionType(T, New->getLocation()))          continue; @@ -2262,10 +2283,24 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,        EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);        ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs);        if (E.isUsable()) +        E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); +     +      if (E.isUsable()) { +        SourceLocation ErrLoc; +        llvm::APSInt NoexceptVal;          NoexceptExpr = E.take(); +        if (!NoexceptExpr->isTypeDependent() && +            !NoexceptExpr->isValueDependent() && +            !NoexceptExpr->isIntegerConstantExpr(NoexceptVal, SemaRef.Context, +                                                 &ErrLoc, /*evaluated=*/false)){ +          SemaRef.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression) +            << NoexceptExpr->getSourceRange(); +          NoexceptExpr = 0; +        } +      }      } -    // Rebuild the function type  +    // Rebuild the function type      FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();      EPI.ExceptionSpecType = Proto->getExceptionSpecType(); @@ -2283,6 +2318,13 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,                                                   EPI));    } +  // C++0x [dcl.constexpr]p6: If the instantiated template specialization of +  // a constexpr function template satisfies the requirements for a constexpr +  // function, then it is a constexpr function. +  if (Tmpl->isConstexpr() && +      SemaRef.CheckConstexprFunctionDecl(New, Sema::CCK_Instantiation)) +    New->setConstexpr(true); +    const FunctionDecl* Definition = Tmpl;    // Get the definition. Leaves the variable unchanged if undefined. @@ -2337,8 +2379,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    if (Function->isInvalidDecl() || Function->isDefined())      return; -  // Never instantiate an explicit specialization. -  if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) +  // Never instantiate an explicit specialization except if it is a class scope +  // explicit specialization. +  if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && +      !Function->getClassScopeSpecializationPattern())      return;    // Find the function body that we'll be substituting. @@ -2362,7 +2406,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    }    // Call the LateTemplateParser callback if there a need to late parse -  // a templated function definition.  +  // a templated function definition.    if (!Pattern && PatternDecl->isLateTemplateParsed() &&        LateTemplateParser) {      LateTemplateParser(OpaqueParser, PatternDecl); @@ -2372,16 +2416,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    if (!Pattern && !PatternDecl->isDefaulted()) {      if (DefinitionRequired) {        if (Function->getPrimaryTemplate()) -        Diag(PointOfInstantiation,  +        Diag(PointOfInstantiation,               diag::err_explicit_instantiation_undefined_func_template)            << Function->getPrimaryTemplate();        else -        Diag(PointOfInstantiation,  +        Diag(PointOfInstantiation,               diag::err_explicit_instantiation_undefined_member)            << 1 << Function->getDeclName() << Function->getDeclContext(); -       +        if (PatternDecl) -        Diag(PatternDecl->getLocation(),  +        Diag(PatternDecl->getLocation(),               diag::note_explicit_instantiation_here);        Function->setInvalidDecl();      } else if (Function->getTemplateSpecializationKind() @@ -2404,19 +2448,19 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);    if (Inst) -    return;   -   +    return; +    // If we're performing recursive template instantiation, create our own    // queue of pending implicit instantiations that we will instantiate later,    // while we're still within our own instantiation context. -  llvm::SmallVector<VTableUse, 16> SavedVTableUses; +  SmallVector<VTableUse, 16> SavedVTableUses;    std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;    if (Recursive) {      VTableUses.swap(SavedVTableUses);      PendingInstantiations.swap(SavedPendingInstantiations);    } -  EnterExpressionEvaluationContext EvalContext(*this,  +  EnterExpressionEvaluationContext EvalContext(*this,                                                 Sema::PotentiallyEvaluated);    ActOnStartOfFunctionDef(0, Function); @@ -2445,11 +2489,11 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,        ++FParamIdx;        continue;      } -     +      // Expand the parameter pack.      Scope.MakeInstantiatedLocalArgPack(PatternParam); -    for (unsigned NumFParams = Function->getNumParams();  -         FParamIdx < NumFParams;  +    for (unsigned NumFParams = Function->getNumParams(); +         FParamIdx < NumFParams;           ++FParamIdx) {        ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);        FunctionParam->setDeclName(PatternParam->getDeclName()); @@ -2481,7 +2525,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,      if (Body.isInvalid())        Function->setInvalidDecl(); -     +      ActOnFinishFunctionBody(Function, Body.get(),                              /*IsInstantiation=*/true);    } @@ -2545,7 +2589,7 @@ void Sema::InstantiateStaticDataMemberDefinition(    // Find the out-of-line definition of this static data member.    VarDecl *Def = Var->getInstantiatedFromStaticDataMember();    assert(Def && "This data member was not instantiated from a template?"); -  assert(Def->isStaticDataMember() && "Not a static data member?");   +  assert(Def->isStaticDataMember() && "Not a static data member?");    Def = Def->getOutOfLineDefinition();    if (!Def) { @@ -2555,7 +2599,7 @@ void Sema::InstantiateStaticDataMemberDefinition(      // another translation unit.      if (DefinitionRequired) {        Def = Var->getInstantiatedFromStaticDataMember(); -      Diag(PointOfInstantiation,  +      Diag(PointOfInstantiation,             diag::err_explicit_instantiation_undefined_member)          << 2 << Var->getDeclName() << Var->getDeclContext();        Diag(Def->getLocation(), diag::note_explicit_instantiation_here); @@ -2571,12 +2615,12 @@ void Sema::InstantiateStaticDataMemberDefinition(    // Never instantiate an explicit specialization.    if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)      return; -   +    // C++0x [temp.explicit]p9:    //   Except for inline functions, other explicit instantiation declarations    //   have the effect of suppressing the implicit instantiation of the entity    //   to which they refer. -  if (Var->getTemplateSpecializationKind()  +  if (Var->getTemplateSpecializationKind()          == TSK_ExplicitInstantiationDeclaration)      return; @@ -2591,7 +2635,7 @@ void Sema::InstantiateStaticDataMemberDefinition(    // If we're performing recursive template instantiation, create our own    // queue of pending implicit instantiations that we will instantiate later,    // while we're still within our own instantiation context. -  llvm::SmallVector<VTableUse, 16> SavedVTableUses; +  SmallVector<VTableUse, 16> SavedVTableUses;    std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;    if (Recursive) {      VTableUses.swap(SavedVTableUses); @@ -2639,14 +2683,26 @@ void Sema::InstantiateStaticDataMemberDefinition(    }  } +static MultiInitializer CreateMultiInitializer(SmallVectorImpl<Expr*> &Args, +                                               const CXXCtorInitializer *Init) { +  // FIXME: This is a hack that will do slightly the wrong thing for an +  // initializer of the form foo({...}). +  // The right thing to do would be to modify InstantiateInitializer to create +  // the MultiInitializer. +  if (Args.size() == 1 && isa<InitListExpr>(Args[0])) +    return MultiInitializer(Args[0]); +  return MultiInitializer(Init->getLParenLoc(), Args.data(), +                          Args.size(), Init->getRParenLoc()); +} +  void  Sema::InstantiateMemInitializers(CXXConstructorDecl *New,                                   const CXXConstructorDecl *Tmpl,                             const MultiLevelTemplateArgumentList &TemplateArgs) { -  llvm::SmallVector<MemInitTy*, 4> NewInits; +  SmallVector<CXXCtorInitializer*, 4> NewInits;    bool AnyErrors = false; -   +    // Instantiate all the initializers.    for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),                                              InitsEnd = Tmpl->init_end(); @@ -2662,20 +2718,19 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,      ASTOwningVector<Expr*> NewArgs(*this);      SourceLocation EllipsisLoc; -     +      if (Init->isPackExpansion()) {        // This is a pack expansion. We should expand it now.        TypeLoc BaseTL = Init->getBaseClassInfo()->getTypeLoc(); -      llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; +      SmallVector<UnexpandedParameterPack, 2> Unexpanded;        collectUnexpandedParameterPacks(BaseTL, Unexpanded);        bool ShouldExpand = false;        bool RetainExpansion = false;        llvm::Optional<unsigned> NumExpansions; -      if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),  +      if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),                                            BaseTL.getSourceRange(), -                                          Unexpanded.data(),  -                                          Unexpanded.size(), -                                          TemplateArgs, ShouldExpand,  +                                          Unexpanded, +                                          TemplateArgs, ShouldExpand,                                            RetainExpansion,                                            NumExpansions)) {          AnyErrors = true; @@ -2683,22 +2738,22 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,          continue;        }        assert(ShouldExpand && "Partial instantiation of base initializer?"); -       -      // Loop over all of the arguments in the argument pack(s),  + +      // Loop over all of the arguments in the argument pack(s),        for (unsigned I = 0; I != *NumExpansions; ++I) {          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);          // Instantiate the initializer. -        if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs,  +        if (InstantiateInitializer(Init->getInit(), TemplateArgs,                                     LParenLoc, NewArgs, RParenLoc)) {            AnyErrors = true;            break;          }          // Instantiate the base type. -        TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),  -                                              TemplateArgs,  -                                              Init->getSourceLocation(),  +        TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), +                                              TemplateArgs, +                                              Init->getSourceLocation(),                                                New->getDeclName());          if (!BaseTInfo) {            AnyErrors = true; @@ -2706,52 +2761,45 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,          }          // Build the initializer. -        MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),  -                                                     BaseTInfo, -                                                     (Expr **)NewArgs.data(), -                                                     NewArgs.size(), -                                                     Init->getLParenLoc(), -                                                     Init->getRParenLoc(), +        MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); +        MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), +                                                     BaseTInfo, MultiInit,                                                       New->getParent(),                                                       SourceLocation());          if (NewInit.isInvalid()) {            AnyErrors = true;            break;          } -         +          NewInits.push_back(NewInit.get());          NewArgs.clear();        } -       +        continue;      }      // Instantiate the initializer. -    if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs,  +    if (InstantiateInitializer(Init->getInit(), TemplateArgs,                                 LParenLoc, NewArgs, RParenLoc)) {        AnyErrors = true;        continue;      } -     +      MemInitResult NewInit;      if (Init->isBaseInitializer()) { -      TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),  -                                            TemplateArgs,  -                                            Init->getSourceLocation(),  +      TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), +                                            TemplateArgs, +                                            Init->getSourceLocation(),                                              New->getDeclName());        if (!BaseTInfo) {          AnyErrors = true;          New->setInvalidDecl();          continue;        } -       -      NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, -                                     (Expr **)NewArgs.data(), -                                     NewArgs.size(), -                                     Init->getLParenLoc(), -                                     Init->getRParenLoc(), -                                     New->getParent(), -                                     EllipsisLoc); + +      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); +      NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, MultiInit, +                                     New->getParent(), EllipsisLoc);      } else if (Init->isMemberInitializer()) {        FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(                                                       Init->getMemberLocation(), @@ -2763,11 +2811,9 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,          continue;        } -      NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(), -                                       NewArgs.size(), -                                       Init->getSourceLocation(), -                                       Init->getLParenLoc(), -                                       Init->getRParenLoc()); +      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); +      NewInit = BuildMemberInitializer(Member, MultiInit, +                                       Init->getSourceLocation());      } else if (Init->isIndirectMemberInitializer()) {        IndirectFieldDecl *IndirectMember =           cast_or_null<IndirectFieldDecl>(FindInstantiatedDecl( @@ -2777,14 +2823,12 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,        if (!IndirectMember) {          AnyErrors = true;          New->setInvalidDecl(); -        continue;         +        continue;        } -       -      NewInit = BuildMemberInitializer(IndirectMember, (Expr **)NewArgs.data(), -                                       NewArgs.size(), -                                       Init->getSourceLocation(), -                                       Init->getLParenLoc(), -                                       Init->getRParenLoc()); + +      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); +      NewInit = BuildMemberInitializer(IndirectMember, MultiInit, +                                       Init->getSourceLocation());      }      if (NewInit.isInvalid()) { @@ -2794,7 +2838,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,        // FIXME: It would be nice if ASTOwningVector had a release function.        NewArgs.take(); -      NewInits.push_back((MemInitTy *)NewInit.get()); +      NewInits.push_back(NewInit.get());      }    } @@ -2824,20 +2868,20 @@ static bool isInstantiationOf(ClassTemplateDecl *Pattern,  static bool isInstantiationOf(FunctionTemplateDecl *Pattern,                                FunctionTemplateDecl *Instance) {    Pattern = Pattern->getCanonicalDecl(); -   +    do {      Instance = Instance->getCanonicalDecl();      if (Pattern == Instance) return true;      Instance = Instance->getInstantiatedFromMemberTemplate();    } while (Instance); -   +    return false;  } -static bool  +static bool  isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern,                    ClassTemplatePartialSpecializationDecl *Instance) { -  Pattern  +  Pattern      = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl());    do {      Instance = cast<ClassTemplatePartialSpecializationDecl>( @@ -2846,7 +2890,7 @@ isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern,        return true;      Instance = Instance->getInstantiatedFromMember();    } while (Instance); -   +    return false;  } @@ -3052,11 +3096,11 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,      typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;      llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found        = CurrentInstantiationScope->findInstantiationOf(D); -     +      if (Found) {        if (Decl *FD = Found->dyn_cast<Decl *>())          return cast<NamedDecl>(FD); -       +        unsigned PackIdx = ArgumentPackSubstitutionIndex;        return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]);      } @@ -3064,10 +3108,10 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,      // If we didn't find the decl, then we must have a label decl that hasn't      // been found yet.  Lazily instantiate it and return it now.      assert(isa<LabelDecl>(D)); -     +      Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);      assert(Inst && "Failed to instantiate label??"); -     +      CurrentInstantiationScope->InstantiatedLocal(D, Inst);      return cast<LabelDecl>(Inst);    } @@ -3075,7 +3119,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,    if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {      if (!Record->isDependentContext())        return D; -     +      // If the RecordDecl is actually the injected-class-name or a      // "templated" declaration for a class template, class template      // partial specialization, or a member class of a class template, @@ -3083,7 +3127,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,      // or partial specialization to find the new DeclContext.      QualType T;      ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate(); -     +      if (ClassTemplate) {        T = ClassTemplate->getInjectedClassNameSpecialization();      } else if (ClassTemplatePartialSpecializationDecl *PartialSpec @@ -3096,26 +3140,26 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,        assert(isa<InjectedClassNameType>(T) &&               "type of partial specialization is not an InjectedClassNameType");        T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType(); -    }   -     +    } +      if (!T.isNull()) {        // Substitute into the injected-class-name to get the type        // corresponding to the instantiation we want, which may also be        // the current instantiation (if we're in a template        // definition). This substitution should never fail, since we        // know we can instantiate the injected-class-name or we -      // wouldn't have gotten to the injected-class-name!   +      // wouldn't have gotten to the injected-class-name!        // FIXME: Can we use the CurrentInstantiationScope to avoid this        // extra instantiation in the common case?        T = SubstType(T, TemplateArgs, Loc, DeclarationName());        assert(!T.isNull() && "Instantiation of injected-class-name cannot fail."); -     +        if (!T->isDependentType()) {          assert(T->isRecordType() && "Instantiation must produce a record type");          return T->getAs<RecordType>()->getDecl();        } -     +        // We are performing "partial" template instantiation to create        // the member declarations for the members of a class template        // specialization. Therefore, D is actually referring to something @@ -3128,7 +3172,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,             DC = DC->getParent()) {          if (ClassTemplateSpecializationDecl *Spec                            = dyn_cast<ClassTemplateSpecializationDecl>(DC)) -          if (isInstantiationOf(ClassTemplate,  +          if (isInstantiationOf(ClassTemplate,                                  Spec->getSpecializedTemplate()))              return Spec; @@ -3139,10 +3183,10 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,        // We're performing "instantiation" of a member of the current        // instantiation while we are type-checking the        // definition. Compute the declaration context and return that. -      assert(!SawNonDependentContext &&  +      assert(!SawNonDependentContext &&               "No dependent context while instantiating record");        DeclContext *DC = computeDeclContext(T); -      assert(DC &&  +      assert(DC &&               "Unable to find declaration for the current instantiation");        return cast<CXXRecordDecl>(DC);      } @@ -3153,7 +3197,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,    if (!ParentDC->isDependentContext())      return D; -   +    ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs);    if (!ParentDC)      return 0; @@ -3207,7 +3251,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,          // declaration failed to instantiate. There's no point in complaining          // further, since this is normal in invalid code.        } else if (IsBeingInstantiated) { -        // The class in which this member exists is currently being  +        // The class in which this member exists is currently being          // instantiated, and we haven't gotten around to instantiating this          // member yet. This can happen when the code uses forward declarations          // of member classes, and introduces ordering dependencies via @@ -3221,7 +3265,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,          llvm_unreachable("Unable to find instantiation of declaration!");        }      } -     +      D = Result;    } @@ -3231,6 +3275,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,  /// \brief Performs template instantiation for all implicit template  /// instantiations we have seen until this point.  void Sema::PerformPendingInstantiations(bool LocalOnly) { +  // Load pending instantiations from the external source. +  if (!LocalOnly && ExternalSource) { +    SmallVector<std::pair<ValueDecl *, SourceLocation>, 4> Pending; +    ExternalSource->ReadPendingInstantiations(Pending); +    PendingInstantiations.insert(PendingInstantiations.begin(), +                                 Pending.begin(), Pending.end()); +  } +    while (!PendingLocalImplicitInstantiations.empty() ||           (!LocalOnly && !PendingInstantiations.empty())) {      PendingImplicitInstantiation Inst; @@ -3267,7 +3319,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) {      // and removed the need for implicit instantiation.      switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) {      case TSK_Undeclared: -      assert(false && "Cannot instantitiate an undeclared specialization."); +      llvm_unreachable("Cannot instantitiate an undeclared specialization.");      case TSK_ExplicitInstantiationDeclaration:      case TSK_ExplicitSpecialization:        continue;  // No longer need to instantiate this type. | 
