diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 1aa69bd35d67e..96abeed824930 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -199,6 +199,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const { case DefaultTemplateArgumentChecking: case DeclaringSpecialMember: case DefiningSynthesizedFunction: + case ExceptionSpecEvaluation: return false; // This function should never be called when Kind's value is Memoization. @@ -621,6 +622,12 @@ void Sema::PrintInstantiationStack() { break; } + case CodeSynthesisContext::ExceptionSpecEvaluation: + Diags.Report(Active->PointOfInstantiation, + diag::note_evaluating_exception_spec_here) + << cast<FunctionDecl>(Active->Entity); + break; + case CodeSynthesisContext::ExceptionSpecInstantiation: Diags.Report(Active->PointOfInstantiation, diag::note_template_exception_spec_instantiation_here) @@ -668,7 +675,7 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { // context, depending on what else is on the stack. if (isa<TypeAliasTemplateDecl>(Active->Entity)) break; - // Fall through. + LLVM_FALLTHROUGH; case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: case CodeSynthesisContext::ExceptionSpecInstantiation: // This is a template instantiation, so there is no SFINAE. @@ -695,6 +702,12 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { // there is no SFINAE. return None; + case CodeSynthesisContext::ExceptionSpecEvaluation: + // FIXME: This should not be treated as a SFINAE context, because + // we will cache an incorrect exception specification. However, clang + // bootstrap relies this! See PR31692. + break; + case CodeSynthesisContext::Memoization: break; } @@ -894,7 +907,7 @@ namespace { QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec); ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, @@ -1154,7 +1167,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) { if (!E->isTypeDependent()) return E; - return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType()); + return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind()); } ExprResult @@ -1414,7 +1427,7 @@ template<typename Fn> QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals, + Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) { // We need a local instantiation scope for this function prototype. LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); @@ -1653,7 +1666,7 @@ TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T, SourceLocation Loc, DeclarationName Entity, CXXRecordDecl *ThisContext, - unsigned ThisTypeQuals) { + Qualifiers ThisTypeQuals) { assert(!CodeSynthesisContexts.empty() && "Cannot perform an instantiation without some context on the " "instantiation stack"); @@ -1708,7 +1721,7 @@ void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, Proto->getExtProtoInfo().ExceptionSpec; SmallVector<QualType, 4> ExceptionStorage; - if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getLocEnd(), + if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getEndLoc(), ESI, ExceptionStorage, Args)) // On error, recover by dropping the exception specification. ESI.Type = EST_None; @@ -1789,7 +1802,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, ExprResult NewArg = SubstExpr(Arg, TemplateArgs); if (NewArg.isUsable()) { // It would be nice if we still had this. - SourceLocation EqualLoc = NewArg.get()->getLocStart(); + SourceLocation EqualLoc = NewArg.get()->getBeginLoc(); SetParamDefaultArgument(NewParm, NewArg.get(), EqualLoc); } } else { @@ -2135,7 +2148,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl); CXXRecordDecl *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()); - CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0, + CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(), ND && ND->isCXXInstanceMember()); Attr *NewAttr = @@ -2303,7 +2316,7 @@ bool Sema::InstantiateInClassInitializer( Diag(PointOfInstantiation, diag::err_in_class_initializer_not_yet_parsed) << OutermostClass << Pattern; - Diag(Pattern->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed); + Diag(Pattern->getEndLoc(), diag::note_in_class_initializer_not_yet_parsed); Instantiation->setInvalidDecl(); return true; } @@ -2330,14 +2343,14 @@ bool Sema::InstantiateInClassInitializer( // Instantiate the initializer. ActOnStartCXXInClassMemberInitializer(); - CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), /*TypeQuals=*/0); + CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers()); ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs, /*CXXDirectInit=*/false); Expr *Init = NewInit.get(); assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class"); ActOnFinishCXXInClassMemberInitializer( - Instantiation, Init ? Init->getLocStart() : SourceLocation(), Init); + Instantiation, Init ? Init->getBeginLoc() : SourceLocation(), Init); if (auto *L = getASTMutationListener()) L->DefaultMemberInitializerInstantiated(Instantiation); @@ -2561,10 +2574,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, for (auto *D : Instantiation->decls()) { bool SuppressNew = false; if (auto *Function = dyn_cast<FunctionDecl>(D)) { - if (FunctionDecl *Pattern - = Function->getInstantiatedFromMemberFunction()) { - MemberSpecializationInfo *MSInfo - = Function->getMemberSpecializationInfo(); + if (FunctionDecl *Pattern = + Function->getInstantiatedFromMemberFunction()) { + + if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + + MemberSpecializationInfo *MSInfo = + Function->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) @@ -2605,6 +2622,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, continue; if (Var->isStaticDataMember()) { + if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); assert(MSInfo && "No member specialization information?"); if (MSInfo->getTemplateSpecializationKind() @@ -2636,6 +2656,9 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation, } } } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) { + if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>()) + continue; + // Always skip the injected-class-name, along with any // redeclarations of nested classes, since both would cause us // to try to instantiate the members of a class twice. |