Author: Chuanqi Xu Date: 2023-02-14T17:15:33+08:00 New Revision: 1ba93c3c30dcdf2659e3020ba462e0025187d8e1
URL: https://github.com/llvm/llvm-project/commit/1ba93c3c30dcdf2659e3020ba462e0025187d8e1 DIFF: https://github.com/llvm/llvm-project/commit/1ba93c3c30dcdf2659e3020ba462e0025187d8e1.diff LOG: [Modules] Don't re-generate template specialization in the importer Close https://github.com/llvm/llvm-project/issues/60693. In this issue, we can find that the importer will try to generate the template specialization again in the importer, which is not good and wastes time. This patch tries to address the problem. Added: clang/test/Modules/pr60693.cppm Modified: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/Serialization/ASTWriterDecl.cpp clang/test/Modules/pr59780.cppm Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 006063e21eb3d..0f4decc14579b 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3043,7 +3043,7 @@ class ASTContext : public RefCountedBase<ASTContext> { } GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const; - GVALinkage GetGVALinkageForVariable(const VarDecl *VD); + GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const; /// Determines if the decl can be CodeGen'ed or deserialized from PCH /// lazily, only when used; this is only relevant for function or file scoped diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a188837d4144c..a5f7f6a019f87 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11764,7 +11764,7 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context, llvm_unreachable("Invalid Linkage!"); } -GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) { +GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) const { return adjustGVALinkageForExternalDefinitionKind(*this, VD, adjustGVALinkageForAttributes(*this, VD, basicGVALinkageForVariable(*this, VD))); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 9e1e58a7fa7e2..69d192612bccf 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1068,7 +1068,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { if (D->getStorageDuration() == SD_Static) { bool ModulesCodegen = false; if (Writer.WritingModule && - !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo()) { + !D->getDescribedVarTemplate()) { // When building a C++20 module interface unit or a partition unit, a // strong definition in the module interface is provided by the // compilation of that unit, not by its users. (Inline variables are still @@ -1077,7 +1077,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { (Writer.WritingModule->isInterfaceOrPartition() || (D->hasAttr<DLLExportAttr>() && Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) && - Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal; + Writer.Context->GetGVALinkageForVariable(D) >= GVA_StrongExternal; } Record.push_back(ModulesCodegen); if (ModulesCodegen) @@ -2550,7 +2550,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { // compilation of that unit, not by its users. (Inline functions are still // emitted in module users.) Linkage = Writer->Context->GetGVALinkageForFunction(FD); - ModulesCodegen = *Linkage == GVA_StrongExternal; + ModulesCodegen = *Linkage >= GVA_StrongExternal; } if (Writer->Context->getLangOpts().ModulesCodegen || (FD->hasAttr<DLLExportAttr>() && diff --git a/clang/test/Modules/pr59780.cppm b/clang/test/Modules/pr59780.cppm index 9578325b976ba..d4bbd52c13f1a 100644 --- a/clang/test/Modules/pr59780.cppm +++ b/clang/test/Modules/pr59780.cppm @@ -33,8 +33,8 @@ struct Y<int> { int Y<int>::value = 0; -// CHECK-NOT: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global -// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global +// CHECK-NOT: @_ZW1a1xIiE = {{.*}}external{{.*}}global +// CHECK-NOT: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global //--- use.cpp import a; @@ -42,5 +42,5 @@ int foo() { return x<int> + Y<int>::value; } -// CHECK: @_ZW1a1xIiE = {{.*}}available_externally{{.*}}global -// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}available_externally{{.*}}global +// CHECK: @_ZW1a1xIiE = {{.*}}external{{.*}}global +// CHECK: @_ZNW1a1YIiE5valueE = {{.*}}external{{.*}}global diff --git a/clang/test/Modules/pr60693.cppm b/clang/test/Modules/pr60693.cppm new file mode 100644 index 0000000000000..117a0f2753d0a --- /dev/null +++ b/clang/test/Modules/pr60693.cppm @@ -0,0 +1,54 @@ +// Address: https://github.com/llvm/llvm-project/issues/60693 +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm -emit-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -fmodule-file=a=%t/a.pcm %t/c.cpp -S -emit-llvm -disable-llvm-passes -o - | FileCheck %t/c.cpp + +//--- a.cppm +export module a; + +constexpr bool f() { + for (unsigned n = 0; n != 10; ++n) { + } + return true; +} + +export template<typename> +struct s { + static constexpr auto a = f(); + static constexpr auto b = f(); + static constexpr auto c = f(); + static constexpr auto d = f(); + int foo() { + return 43; + } + int bar() { + return 44; + } +}; + +template struct s<int>; +template struct s<long>; + +//--- c.cpp +import a; + +extern "C" int use() { + s<int> _; + return _.a + _.b + _.c + _.d; +} + +extern "C" long use2() { + s<long> _; + return _.foo(); +} + +// CHECK: define{{.*}}@use( +// CHECK-NOT: } +// CHECK: ret{{.*}} 4 + +// CHECK: declare{{.*}}@_ZNW1a1sIlE3fooEv +// CHECK-NOT: _ZNW1a1sIlE3barEv _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits