Author: erichkeane Date: Mon Aug 13 11:33:20 2018 New Revision: 339597 URL: http://llvm.org/viewvc/llvm-project?rev=339597&view=rev Log: Enforce instantiation of template multiversion functions
Multiversioned member functions inside of a template type were not properly being emitted. The solution to this is to simply ensure that their bodies are correctly evaluated/assigned during template instantiation. Modified: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/test/CodeGenCXX/attr-target-mv-member-funcs.cpp Modified: cfe/trunk/include/clang/AST/ASTContext.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=339597&r1=339596&r2=339597&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTContext.h (original) +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 13 11:33:20 2018 @@ -2743,7 +2743,7 @@ public: /// predicate. void forEachMultiversionedFunctionVersion( const FunctionDecl *FD, - llvm::function_ref<void(const FunctionDecl *)> Pred) const; + llvm::function_ref<void(FunctionDecl *)> Pred) const; const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD); Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=339597&r1=339596&r2=339597&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 13 11:33:20 2018 @@ -9819,7 +9819,7 @@ bool ASTContext::DeclMustBeEmitted(const void ASTContext::forEachMultiversionedFunctionVersion( const FunctionDecl *FD, - llvm::function_ref<void(const FunctionDecl *)> Pred) const { + llvm::function_ref<void(FunctionDecl *)> Pred) const { assert(FD->isMultiVersion() && "Only valid for multiversioned functions"); llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls; FD = FD->getCanonicalDecl(); Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=339597&r1=339596&r2=339597&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 13 11:33:20 2018 @@ -5175,10 +5175,20 @@ void Sema::PerformPendingInstantiations( if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) { bool DefinitionRequired = Function->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; - InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true, - DefinitionRequired, true); - if (Function->isDefined()) - Function->setInstantiationIsPending(false); + if (Function->isMultiVersion()) { + getASTContext().forEachMultiversionedFunctionVersion( + Function, [this, Inst, DefinitionRequired](FunctionDecl *CurFD) { + InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, CurFD, true, + DefinitionRequired, true); + if (CurFD->isDefined()) + CurFD->setInstantiationIsPending(false); + }); + } else { + InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, Function, true, + DefinitionRequired, true); + if (Function->isDefined()) + Function->setInstantiationIsPending(false); + } continue; } Modified: cfe/trunk/test/CodeGenCXX/attr-target-mv-member-funcs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/attr-target-mv-member-funcs.cpp?rev=339597&r1=339596&r2=339597&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/attr-target-mv-member-funcs.cpp (original) +++ cfe/trunk/test/CodeGenCXX/attr-target-mv-member-funcs.cpp Mon Aug 13 11:33:20 2018 @@ -111,13 +111,12 @@ int templ_use() { // CHECK: call i32 @_ZN5templIiE3fooEi.ifunc // CHECK: call i32 @_ZN5templIdE3fooEi.ifunc - // CHECK: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2 // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi -// + // CHECK: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge @@ -135,3 +134,12 @@ int templ_use() { // CHECK: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32) // CHECK: ret i32 2 +// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi.sse4.2 +// CHECK: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge +// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi.arch_ivybridge +// CHECK: define linkonce_odr i32 @_ZN5templIiE3fooEi + +// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi.sse4.2 +// CHECK: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge +// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi.arch_ivybridge +// CHECK: define linkonce_odr i32 @_ZN5templIdE3fooEi _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits