Author: Chuanqi Xu
Date: 2024-07-10T10:58:18+08:00
New Revision: 91d40ef6e369a73b0147d9153a95c3bc63e14102

URL: 
https://github.com/llvm/llvm-project/commit/91d40ef6e369a73b0147d9153a95c3bc63e14102
DIFF: 
https://github.com/llvm/llvm-project/commit/91d40ef6e369a73b0147d9153a95c3bc63e14102.diff

LOG: Revert "[C++20] [Modules] [Itanium ABI] Generate the vtable in the module 
unit of dynamic classes (#75912)"

This reverts commit 18f3bcbb13ca83d33223b00761d8cddf463e9ffb, 
15bb02650e26875c48889053d6a9697444583721 and
99873b35da7ecb905143c8a6b8deca4d4416f1a9.

See the post commit message in
https://github.com/llvm/llvm-project/pull/75912 to see the reasons.

Added: 
    

Modified: 
    clang/include/clang/AST/DeclBase.h
    clang/include/clang/Serialization/ASTBitCodes.h
    clang/include/clang/Serialization/ASTReader.h
    clang/include/clang/Serialization/ASTWriter.h
    clang/lib/AST/ASTContext.cpp
    clang/lib/AST/Decl.cpp
    clang/lib/AST/DeclBase.cpp
    clang/lib/CodeGen/CGVTables.cpp
    clang/lib/CodeGen/ItaniumCXXABI.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/lib/Serialization/ASTWriterDecl.cpp
    clang/test/CodeGenCXX/modules-vtable.cppm

Removed: 
    clang/test/CodeGenCXX/pr70585.cppm
    clang/test/Modules/pr97313.cppm


################################################################################
diff  --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 45dac82e54077..06ffc2ce09b89 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -670,16 +670,6 @@ class alignas(8) Decl {
   /// Whether this declaration comes from another module unit.
   bool isInAnotherModuleUnit() const;
 
-  /// Whether this declaration comes from the same module unit being compiled.
-  bool isInCurrentModuleUnit() const;
-
-  /// Whether the definition of the declaration should be emitted in external
-  /// sources.
-  bool shouldEmitInExternalSource() const;
-
-  /// Whether this declaration comes from a named module;
-  bool isInNamedModule() const;
-
   /// Whether this declaration comes from explicit global module.
   bool isFromExplicitGlobalModule() const;
 

diff  --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 38502a23f805e..488994c05dc12 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -721,9 +721,6 @@ enum ASTRecordTypes {
 
   /// Record code for \#pragma clang unsafe_buffer_usage begin/end
   PP_UNSAFE_BUFFER_USAGE = 69,
-
-  /// Record code for vtables to emit.
-  VTABLES_TO_EMIT = 70,
 };
 
 /// Record types used within a source manager block.

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index f41c473c97cd9..76e51ac7ab979 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -790,11 +790,6 @@ class ASTReader
   /// the consumer eagerly.
   SmallVector<GlobalDeclID, 16> EagerlyDeserializedDecls;
 
-  /// The IDs of all vtables to emit. The referenced declarations are passed
-  /// to the consumers's HandleVTable eagerly after passing
-  /// EagerlyDeserializedDecls.
-  SmallVector<GlobalDeclID, 16> VTablesToEmit;
-
   /// The IDs of all tentative definitions stored in the chain.
   ///
   /// Sema keeps track of all tentative definitions in a TU because it has to
@@ -1505,7 +1500,6 @@ class ASTReader
   bool isConsumerInterestedIn(Decl *D);
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
-  void PassVTableToConsumer(CXXRecordDecl *RD);
 
   void finishPendingActions();
   void diagnoseOdrViolations();

diff  --git a/clang/include/clang/Serialization/ASTWriter.h 
b/clang/include/clang/Serialization/ASTWriter.h
index 71a7c28047e31..a0e475ec9f862 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -500,10 +500,6 @@ class ASTWriter : public ASTDeserializationListener,
   std::vector<SourceRange> NonAffectingRanges;
   std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;
 
-  /// A list of classes which need to emit the VTable in the corresponding
-  /// object file.
-  llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;
-
   /// Computes input files that didn't affect compilation of the current 
module,
   /// and initializes data structures necessary for leaving those files out
   /// during \c SourceManager serialization.
@@ -861,8 +857,6 @@ class ASTWriter : public ASTDeserializationListener,
     return PredefinedDecls.count(D);
   }
 
-  void handleVTable(CXXRecordDecl *RD);
-
 private:
   // ASTDeserializationListener implementation
   void ReaderInitialized(ASTReader *Reader) override;
@@ -957,7 +951,6 @@ class PCHGenerator : public SemaConsumer {
 
   void InitializeSema(Sema &S) override { SemaPtr = &S; }
   void HandleTranslationUnit(ASTContext &Ctx) override;
-  void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
   ASTMutationListener *GetASTMutationListener() override;
   ASTDeserializationListener *GetASTDeserializationListener() override;
   bool hasEmittedPCH() const { return Buffer->IsComplete; }

diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 84deaf5429df7..8e35e71d4a23e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12116,7 +12116,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
     return false;
 
   // Variables in other module units shouldn't be forced to be emitted.
-  if (VD->shouldEmitInExternalSource())
+  if (VD->isInAnotherModuleUnit())
     return false;
 
   // Variables that can be needed in other TUs are required.

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 490c4a2fc525c..ecccab08cbaab 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1181,6 +1181,13 @@ Linkage NamedDecl::getLinkageInternal() const {
       .getLinkage();
 }
 
+/// Determine whether D is attached to a named module.
+static bool isInNamedModule(const NamedDecl *D) {
+  if (auto *M = D->getOwningModule())
+    return M->isNamedModule();
+  return false;
+}
+
 static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
   // FIXME: Handle isModulePrivate.
   switch (D->getModuleOwnershipKind()) {
@@ -1190,7 +1197,7 @@ static bool isExportedFromModuleInterfaceUnit(const 
NamedDecl *D) {
     return false;
   case Decl::ModuleOwnershipKind::Visible:
   case Decl::ModuleOwnershipKind::VisibleWhenImported:
-    return D->isInNamedModule();
+    return isInNamedModule(D);
   }
   llvm_unreachable("unexpected module ownership kind");
 }
@@ -1208,7 +1215,7 @@ Linkage NamedDecl::getFormalLinkage() const {
   // [basic.namespace.general]/p2
   //   A namespace is never attached to a named module and never has a name 
with
   //   module linkage.
-  if (isInNamedModule() && InternalLinkage == Linkage::External &&
+  if (isInNamedModule(this) && InternalLinkage == Linkage::External &&
       !isExportedFromModuleInterfaceUnit(
           cast<NamedDecl>(this->getCanonicalDecl())) &&
       !isa<NamespaceDecl>(this))

diff  --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 98c55d6f4eba4..eef946e3aea2e 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1122,31 +1122,23 @@ bool Decl::isInExportDeclContext() const {
 bool Decl::isInAnotherModuleUnit() const {
   auto *M = getOwningModule();
 
-  if (!M || !M->isNamedModule())
+  if (!M)
     return false;
 
-  return M != getASTContext().getCurrentNamedModule();
-}
-
-bool Decl::isInCurrentModuleUnit() const {
-  auto *M = getOwningModule();
-
-  if (!M || !M->isNamedModule())
+  M = M->getTopLevelModule();
+  // FIXME: It is problematic if the header module lives in another module
+  // unit. Consider to fix this by techniques like
+  // ExternalASTSource::hasExternalDefinitions.
+  if (M->isHeaderLikeModule())
     return false;
 
-  return M == getASTContext().getCurrentNamedModule();
-}
-
-bool Decl::shouldEmitInExternalSource() const {
-  ExternalASTSource *Source = getASTContext().getExternalSource();
-  if (!Source)
+  // A global module without parent implies that we're parsing the global
+  // module. So it can't be in another module unit.
+  if (M->isGlobalModule())
     return false;
 
-  return Source->hasExternalDefinitions(this) == ExternalASTSource::EK_Always;
-}
-
-bool Decl::isInNamedModule() const {
-  return getOwningModule() && getOwningModule()->isNamedModule();
+  assert(M->isNamedModule() && "New module kind?");
+  return M != getASTContext().getCurrentNamedModule();
 }
 
 bool Decl::isFromExplicitGlobalModule() const {

diff  --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 10d972ec8a362..7f729d359b82b 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -1079,38 +1079,28 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl 
*RD) {
   if (!RD->isExternallyVisible())
     return llvm::GlobalVariable::InternalLinkage;
 
-  bool IsInNamedModule = RD->isInNamedModule();
-  // If the CXXRecordDecl are not in a module unit, we need to get
-  // its key function. We're at the end of the translation unit, so the current
-  // key function is fully correct.
-  const CXXMethodDecl *keyFunction =
-      IsInNamedModule ? nullptr : Context.getCurrentKeyFunction(RD);
-  if (IsInNamedModule || (keyFunction && !RD->hasAttr<DLLImportAttr>())) {
+  // We're at the end of the translation unit, so the current key
+  // function is fully correct.
+  const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
+  if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
     // If this class has a key function, use that to determine the
     // linkage of the vtable.
     const FunctionDecl *def = nullptr;
-    if (keyFunction && keyFunction->hasBody(def))
+    if (keyFunction->hasBody(def))
       keyFunction = cast<CXXMethodDecl>(def);
 
-    bool IsExternalDefinition =
-        IsInNamedModule ? RD->shouldEmitInExternalSource() : !def;
-
-    TemplateSpecializationKind Kind =
-        IsInNamedModule ? RD->getTemplateSpecializationKind()
-                        : keyFunction->getTemplateSpecializationKind();
-
-    switch (Kind) {
-    case TSK_Undeclared:
-    case TSK_ExplicitSpecialization:
+    switch (keyFunction->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ExplicitSpecialization:
       assert(
-          (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 ||
+          (def || CodeGenOpts.OptimizationLevel > 0 ||
            CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
-          "Shouldn't query vtable linkage without the class in module units, "
-          "key function, optimizations, or debug info");
-      if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0)
+          "Shouldn't query vtable linkage without key function, "
+          "optimizations, or debug info");
+      if (!def && CodeGenOpts.OptimizationLevel > 0)
         return llvm::GlobalVariable::AvailableExternallyLinkage;
 
-      if (keyFunction && keyFunction->isInlined())
+      if (keyFunction->isInlined())
         return !Context.getLangOpts().AppleKext
                    ? llvm::GlobalVariable::LinkOnceODRLinkage
                    : llvm::Function::InternalLinkage;
@@ -1129,7 +1119,7 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
 
       case TSK_ExplicitInstantiationDeclaration:
         llvm_unreachable("Should not have been asked to emit this");
-      }
+    }
   }
 
   // -fapple-kext mode does not support weak linkage, so we must use
@@ -1223,21 +1213,6 @@ bool CodeGenVTables::isVTableExternal(const 
CXXRecordDecl *RD) {
       TSK == TSK_ExplicitInstantiationDefinition)
     return false;
 
-  // Itanium C++ ABI [5.2.3]:
-  // Virtual tables for dynamic classes are emitted as follows:
-  //
-  // - If the class is templated, the tables are emitted in every object that
-  // references any of them.
-  // - Otherwise, if the class is attached to a module, the tables are uniquely
-  // emitted in the object for the module unit in which it is defined.
-  // - Otherwise, if the class has a key function (see below), the tables are
-  // emitted in the object for the translation unit containing the definition 
of
-  // the key function. This is unique if the key function is not inline.
-  // - Otherwise, the tables are emitted in every object that references any of
-  // them.
-  if (RD->isInNamedModule())
-    return RD->shouldEmitInExternalSource();
-
   // Otherwise, if the class doesn't have a key function (possibly
   // anymore), the vtable must be defined here.
   const CXXMethodDecl *keyFunction = 
CGM.getContext().getCurrentKeyFunction(RD);
@@ -1247,7 +1222,13 @@ bool CodeGenVTables::isVTableExternal(const 
CXXRecordDecl *RD) {
   const FunctionDecl *Def;
   // Otherwise, if we don't have a definition of the key function, the
   // vtable must be defined somewhere else.
-  return !keyFunction->hasBody(Def);
+  if (!keyFunction->hasBody(Def))
+    return true;
+
+  assert(Def && "The body of the key function is not assigned to Def?");
+  // If the non-inline key function comes from another module unit, the vtable
+  // must be defined there.
+  return Def->isInAnotherModuleUnit() && !Def->isInlineSpecified();
 }
 
 /// Given that we're currently at the end of the translation unit, and

diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp 
b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 63e36e1b83893..e1d056765a866 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2161,9 +2161,6 @@ bool ItaniumCXXABI::canSpeculativelyEmitVTable(const 
CXXRecordDecl *RD) const {
   if (!canSpeculativelyEmitVTableAsBaseClass(RD))
     return false;
 
-  if (RD->shouldEmitInExternalSource())
-    return false;
-
   // For a complete-object vtable (or more specifically, for the VTT), we need
   // to be able to speculatively emit the vtables of all dynamic virtual bases.
   for (const auto &B : RD->vbases()) {

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 97e1f7e05e44e..d1c7b9d5ae507 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10094,7 +10094,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
     // check at the end of the TU (or when the PMF starts) to see that we
     // have a definition at that point.
     if (isInline && !D.isFunctionDefinition() && getLangOpts().CPlusPlus20 &&
-        NewFD->isInNamedModule()) {
+        NewFD->hasOwningModule() && NewFD->getOwningModule()->isNamedModule()) 
{
       PendingInlineFuncDecls.insert(NewFD);
     }
   }
@@ -18031,15 +18031,6 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl 
*TagD,
       if (NumInitMethods > 1 || !Def->hasInitMethod())
         Diag(RD->getLocation(), diag::err_sycl_special_type_num_init_method);
     }
-
-    // If we're defining a dynamic class in a module interface unit, we always
-    // need to produce the vtable for it even if the vtable is not used in the
-    // current TU.
-    //
-    // The case that the current class is not dynamic is handled in
-    // MarkVTableUsed.
-    if (getCurrentModule() && getCurrentModule()->isInterfaceOrPartition())
-      MarkVTableUsed(RD->getLocation(), RD, /*DefinitionRequired=*/true);
   }
 
   // Exit this scope of this tag's definition.

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 490cd6e864c43..a7da5285ad0e4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -18455,15 +18455,11 @@ bool Sema::DefineUsedVTables() {
 
     bool DefineVTable = true;
 
+    // If this class has a key function, but that key function is
+    // defined in another translation unit, we don't need to emit the
+    // vtable even though we're using it.
     const CXXMethodDecl *KeyFunction = Context.getCurrentKeyFunction(Class);
-    // V-tables for non-template classes with an owning module are always
-    // uniquely emitted in that module.
-    if (Class->isInCurrentModuleUnit())
-      DefineVTable = true;
-    else if (KeyFunction && !KeyFunction->hasBody()) {
-      // If this class has a key function, but that key function is
-      // defined in another translation unit, we don't need to emit the
-      // vtable even though we're using it.
+    if (KeyFunction && !KeyFunction->hasBody()) {
       // The key function is in another translation unit.
       DefineVTable = false;
       TemplateSpecializationKind TSK =
@@ -18508,7 +18504,7 @@ bool Sema::DefineUsedVTables() {
     DefinedAnything = true;
     MarkVirtualMembersReferenced(Loc, Class);
     CXXRecordDecl *Canonical = Class->getCanonicalDecl();
-    if (VTablesUsed[Canonical] && !Class->shouldEmitInExternalSource())
+    if (VTablesUsed[Canonical])
       Consumer.HandleVTable(Class);
 
     // Warn if we're emitting a weak vtable. The vtable will be weak if there 
is

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 079ac3f0e3545..afdeccaf93a9d 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3921,13 +3921,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       }
       break;
 
-    case VTABLES_TO_EMIT:
-      if (F.Kind == MK_MainFile ||
-          getContext().getLangOpts().BuildingPCHWithObjectFile)
-        for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
-          VTablesToEmit.push_back(ReadDeclID(F, Record, I));
-      break;
-
     case IMPORTED_MODULES:
       if (!F.isModule()) {
         // If we aren't loading a module (which has its own exports), make
@@ -8117,10 +8110,6 @@ void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
     Consumer->HandleInterestingDecl(DeclGroupRef(D));
 }
 
-void ASTReader::PassVTableToConsumer(CXXRecordDecl *RD) {
-  Consumer->HandleVTable(RD);
-}
-
 void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
   this->Consumer = Consumer;
 

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index cf3737c5a501d..cbaf1b0a98c61 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -4235,13 +4235,6 @@ void ASTReader::PassInterestingDeclsToConsumer() {
 
   // If we add any new potential interesting decl in the last call, consume it.
   ConsumingPotentialInterestingDecls();
-
-  for (GlobalDeclID ID : VTablesToEmit) {
-    auto *RD = cast<CXXRecordDecl>(GetDecl(ID));
-    assert(!RD->shouldEmitInExternalSource());
-    PassVTableToConsumer(RD);
-  }
-  VTablesToEmit.clear();
 }
 
 void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index c88fb002cb8ec..5b5b468532f32 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -927,7 +927,6 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS);
   RECORD(PP_ASSUME_NONNULL_LOC);
   RECORD(PP_UNSAFE_BUFFER_USAGE);
-  RECORD(VTABLES_TO_EMIT);
 
   // SourceManager Block.
   BLOCK(SOURCE_MANAGER_BLOCK);
@@ -3962,10 +3961,6 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
     Stream.EmitRecord(INTERESTING_IDENTIFIERS, InterestingIdents);
 }
 
-void ASTWriter::handleVTable(CXXRecordDecl *RD) {
-  PendingEmittingVTables.push_back(RD);
-}
-
 
//===----------------------------------------------------------------------===//
 // DeclContext's Name Lookup Table Serialization
 
//===----------------------------------------------------------------------===//
@@ -5168,13 +5163,6 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema 
&SemaRef) {
   // Write all of the DeclsToCheckForDeferredDiags.
   for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
     GetDeclRef(D);
-
-  // Write all classes need to emit the vtable definitions if required.
-  if (isWritingStdCXXNamedModules())
-    for (CXXRecordDecl *RD : PendingEmittingVTables)
-      GetDeclRef(RD);
-  else
-    PendingEmittingVTables.clear();
 }
 
 void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
@@ -5329,17 +5317,6 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
   }
   if (!DeleteExprsToAnalyze.empty())
     Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
-
-  RecordData VTablesToEmit;
-  for (CXXRecordDecl *RD : PendingEmittingVTables) {
-    if (!wasDeclEmitted(RD))
-      continue;
-
-    AddDeclRef(RD, VTablesToEmit);
-  }
-
-  if (!VTablesToEmit.empty())
-    Stream.EmitRecord(VTABLES_TO_EMIT, VTablesToEmit);
 }
 
 ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
@@ -6587,12 +6564,10 @@ void ASTRecordWriter::AddCXXDefinitionData(const 
CXXRecordDecl *D) {
     // computed.
     Record->push_back(D->getODRHash());
 
-  bool ModulesCodegen =
-      !D->isDependentType() &&
-     (Writer->Context->getLangOpts().ModulesDebugInfo ||
-      D->isInNamedModule());
-  Record->push_back(ModulesCodegen);
-  if (ModulesCodegen)
+  bool ModulesDebugInfo =
+      Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType();
+  Record->push_back(ModulesDebugInfo);
+  if (ModulesDebugInfo)
     Writer->AddDeclRef(D, Writer->ModularCodegenDecls);
 
   // IsLambda bit is already saved.

diff  --git a/clang/lib/Serialization/ASTWriterDecl.cpp 
b/clang/lib/Serialization/ASTWriterDecl.cpp
index 59d94c3d79824..b6583c54c9ba1 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1537,14 +1537,8 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) 
{
   if (D->isThisDeclarationADefinition())
     Record.AddCXXDefinitionData(D);
 
-  if (D->isCompleteDefinition() && D->isInNamedModule())
-    Writer.AddDeclRef(D, Writer.ModularCodegenDecls);
-
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  //
-  // FIXME: Avoid adding the key function if the class is defined in
-  // module purview since the key function is meaningless in module purview.
   if (D->isCompleteDefinition())
     Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 

diff  --git a/clang/test/CodeGenCXX/modules-vtable.cppm 
b/clang/test/CodeGenCXX/modules-vtable.cppm
index 5cc3504d72628..fb179b1de4880 100644
--- a/clang/test/CodeGenCXX/modules-vtable.cppm
+++ b/clang/test/CodeGenCXX/modules-vtable.cppm
@@ -24,8 +24,6 @@
 // RUN:     %t/M-A.cppm -o %t/M-A.pcm
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 
-fmodule-file=M:A=%t/M-A.pcm \
 // RUN:     %t/M-B.cppm  -emit-llvm -o - | FileCheck %t/M-B.cppm
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \
-// RUN:     %t/M-A.pcm  -emit-llvm -o - | FileCheck %t/M-A.cppm
 
 //--- Mod.cppm
 export module Mod;
@@ -43,10 +41,9 @@ Base::~Base() {}
 // CHECK: @_ZTSW3Mod4Base = constant
 // CHECK: @_ZTIW3Mod4Base = constant
 
-// With the new Itanium C++ ABI, the linkage of vtables in modules don't need 
to be linkonce ODR.
-// CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant
-// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant
-// CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant
+// CHECK-INLINE: @_ZTVW3Mod4Base = linkonce_odr {{.*}}unnamed_addr constant
+// CHECK-INLINE: @_ZTSW3Mod4Base = linkonce_odr {{.*}}constant
+// CHECK-INLINE: @_ZTIW3Mod4Base = linkonce_odr {{.*}}constant
 
 module :private;
 int private_use() {
@@ -61,13 +58,13 @@ int use() {
     return 43;
 }
 
-// CHECK-NOT: @_ZTSW3Mod4Base
-// CHECK-NOT: @_ZTIW3Mod4Base
-// CHECK: @_ZTVW3Mod4Base = external
+// CHECK-NOT: @_ZTSW3Mod4Base = constant
+// CHECK-NOT: @_ZTIW3Mod4Base = constant
+// CHECK: @_ZTVW3Mod4Base = external unnamed_addr
 
-// CHECK-INLINE-NOT: @_ZTSW3Mod4Base
-// CHECK-INLINE-NOT: @_ZTIW3Mod4Base
-// CHECK-INLINE: @_ZTVW3Mod4Base = external
+// CHECK-INLINE: @_ZTVW3Mod4Base = linkonce_odr {{.*}}unnamed_addr constant
+// CHECK-INLINE: @_ZTSW3Mod4Base = linkonce_odr {{.*}}constant
+// CHECK-INLINE: @_ZTIW3Mod4Base = linkonce_odr {{.*}}constant
 
 // Check the case that the declaration of the key function comes from another
 // module unit but the definition of the key function comes from the current
@@ -85,10 +82,6 @@ int a_use() {
     return 43;
 }
 
-// CHECK: @_ZTVW1M1C = unnamed_addr constant
-// CHECK: @_ZTSW1M1C = constant
-// CHECK: @_ZTIW1M1C = constant
-
 //--- M-B.cppm
 export module M:B;
 import :A;
@@ -100,6 +93,6 @@ int b_use() {
     return 43;
 }
 
-// CHECK: @_ZTVW1M1C = external
-// CHECK-NOT: @_ZTSW1M1C
-// CHECK-NOT: @_ZTIW1M1C
+// CHECK: @_ZTVW1M1C = unnamed_addr constant
+// CHECK: @_ZTSW1M1C = constant
+// CHECK: @_ZTIW1M1C = constant

diff  --git a/clang/test/CodeGenCXX/pr70585.cppm 
b/clang/test/CodeGenCXX/pr70585.cppm
deleted file mode 100644
index ad4e13589d86e..0000000000000
--- a/clang/test/CodeGenCXX/pr70585.cppm
+++ /dev/null
@@ -1,47 +0,0 @@
-// REQUIRES: !system-windows
-
-// RUN: rm -rf %t
-// RUN: split-file %s %t
-// RUN: cd %t
-//
-// RUN: %clang_cc1 -std=c++20 %t/layer1.cppm -triple %itanium_abi_triple \
-// RUN:     -emit-module-interface -o %t/foo-layer1.pcm
-// RUN: %clang_cc1 -std=c++20 %t/layer2.cppm -triple %itanium_abi_triple  \
-// RUN:     -emit-module-interface -fmodule-file=foo:layer1=%t/foo-layer1.pcm \
-// RUN:     -o %t/foo-layer2.pcm
-// RUN: %clang_cc1 -std=c++20 %t/foo-layer1.pcm -emit-llvm -o - | FileCheck 
%t/layer1.cppm
-// RUN: %clang_cc1 -std=c++20 %t/foo-layer2.pcm -emit-llvm -o - \
-// RUN:     -fmodule-file=foo:layer1=%t/foo-layer1.pcm | FileCheck 
%t/layer2.cppm
-//
-// Check the case about emitting object files from sources directly.
-// RUN: %clang_cc1 -std=c++20 %t/layer1.cppm -triple %itanium_abi_triple \
-// RUN:     -emit-llvm -o - | FileCheck %t/layer1.cppm
-// RUN: %clang_cc1 -std=c++20 %t/layer2.cppm -triple %itanium_abi_triple 
-emit-llvm  \
-// RUN:     -fmodule-file=foo:layer1=%t/foo-layer1.pcm -o - | FileCheck 
%t/layer2.cppm
-
-//--- layer1.cppm
-export module foo:layer1;
-struct Fruit {
-    virtual ~Fruit() = default;
-    virtual void eval();
-};
-
-// CHECK-DAG: @_ZTVW3foo5Fruit = unnamed_addr constant
-// CHECK-DAG: @_ZTSW3foo5Fruit = constant
-// CHECK-DAG: @_ZTIW3foo5Fruit = constant
-
-// Testing that:
-// (1) The use of virtual functions won't produce the vtable.
-// (2) The definition of key functions won't produce the vtable.
-//
-//--- layer2.cppm
-export module foo:layer2;
-import :layer1;
-export void layer2_fun() {
-    Fruit *b = new Fruit();
-    b->eval();
-}
-void Fruit::eval() {}
-// CHECK: @_ZTVW3foo5Fruit = external unnamed_addr constant
-// CHECK-NOT: @_ZTSW3foo5Fruit
-// CHECK-NOT: @_ZTIW3foo5Fruit

diff  --git a/clang/test/Modules/pr97313.cppm b/clang/test/Modules/pr97313.cppm
deleted file mode 100644
index ebbd0ee4e2c65..0000000000000
--- a/clang/test/Modules/pr97313.cppm
+++ /dev/null
@@ -1,118 +0,0 @@
-// REQUIRES: !system-windows
-//
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-// RUN: split-file %s %t
-//
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Base.cppm \
-// RUN:     -emit-module-interface -o %t/Base.pcm
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Sub.cppm \
-// RUN:     -emit-module-interface -o %t/Sub.pcm -fprebuilt-module-path=%t
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Sub.pcm \
-// RUN:     -emit-llvm -o %t/Sub.pcm -o - -fprebuilt-module-path=%t | \
-// RUN:     FileCheck %t/Sub.cppm
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/main.cpp \
-// RUN:     -emit-llvm -fprebuilt-module-path=%t -o - | FileCheck %t/main.cpp
-//
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Mod.cppm \
-// RUN:     -emit-module-interface -o %t/Mod.pcm
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Mod.pcm \
-// RUN:     -emit-llvm -o - | FileCheck %t/Mod.cppm
-// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/Use.cpp \
-// RUN:     -emit-llvm -fprebuilt-module-path=%t -o - | \
-// RUN:     FileCheck %t/Use.cpp
-
-//--- Base.cppm
-export module Base;
-
-export template <class>
-class Base
-{
-public:
-    constexpr Base();
-    constexpr virtual ~Base();
-};
-
-template <class X>
-constexpr Base<X>::Base() = default;
-
-template <class X>
-constexpr Base<X>::~Base() = default;
-
-//--- Sub.cppm
-export module Sub;
-export import Base;
-
-export class Sub : public Base<int>
-{
-};
-
-// CHECK: @_ZTIW4Base4BaseIiE = {{.*}}linkonce_odr
-
-//--- main.cpp
-import Sub;
-
-int main()
-{
-    Base<int> *b = new Sub();
-    delete b;
-}
-
-// CHECK: @_ZTIW4Base4BaseIiE = {{.*}}linkonce_odr
-
-//--- Mod.cppm
-export module Mod;
-
-export class NonTemplate {
-public:
-    virtual ~NonTemplate();
-};
-
-// CHECK: @_ZTIW3Mod11NonTemplate = {{.*}}constant
-
-export template <class C>
-class Template {
-public:
-    virtual ~Template();
-};
-
-export template<>
-class Template<char> {
-public:
-    virtual ~Template();
-};
-
-// CHECK: @_ZTIW3Mod8TemplateIcE = {{.*}}constant
-
-export template class Template<unsigned>;
-
-// CHECK: @_ZTIW3Mod8TemplateIjE = {{.*}}weak_odr
-
-export extern template class Template<double>;
-
-auto v = new Template<signed int>();
-
-// CHECK: @_ZTIW3Mod8TemplateIiE = {{.*}}linkonce_odr
-
-//--- Use.cpp
-import Mod;
-
-auto v1 = new NonTemplate();
-auto v2 = new Template<char>();
-auto v3 = new Template<unsigned>();
-auto v4 = new Template<double>();
-auto v5 = new Template<signed int>();
-auto v6 = new Template<NonTemplate>();
-
-// CHECK: @_ZTVW3Mod11NonTemplate = {{.*}}external
-// CHECK: @_ZTVW3Mod8TemplateIcE = {{.*}}external
-// CHECK: @_ZTVW3Mod8TemplateIjE = {{.*}}weak_odr
-// CHECK: @_ZTSW3Mod8TemplateIjE = {{.*}}weak_odr
-// CHECK: @_ZTIW3Mod8TemplateIjE = {{.*}}weak_odr
-// CHECK: @_ZTVW3Mod8TemplateIdE = {{.*}}external
-// CHECK: @_ZTVW3Mod8TemplateIiE = {{.*}}linkonce_odr
-// CHECK: @_ZTSW3Mod8TemplateIiE = {{.*}}linkonce_odr
-// CHECK: @_ZTIW3Mod8TemplateIiE = {{.*}}linkonce_odr
-// CHECK: @_ZTVW3Mod8TemplateIS_11NonTemplateE = {{.*}}linkonce_odr
-// CHECK: @_ZTSW3Mod8TemplateIS_11NonTemplateE = {{.*}}linkonce_odr
-// CHECK: @_ZTIW3Mod8TemplateIS_11NonTemplateE = {{.*}}linkonce_odr


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to