diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 179 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 55 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 8 | ||||
-rw-r--r-- | clang/lib/Parse/ParseAST.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Sema/SemaModule.cpp | 10 |
5 files changed, 11 insertions, 264 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 98b6306..de5cb91 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -618,127 +618,6 @@ void CodeGenModule::EmitCXXThreadLocalInitFunc() { CXXThreadLocals.clear(); } -/* Build the initializer for a C++20 module: - This is arranged to be run only once regardless of how many times the module - might be included transitively. This arranged by using a control variable. - - First we call any initializers for imported modules. - We then call initializers for the Global Module Fragment (if present) - We then call initializers for the current module. - We then call initializers for the Private Module Fragment (if present) -*/ - -void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) { - while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) - CXXGlobalInits.pop_back(); - - // We create the function, even if it is empty, since an importer of this - // module will refer to it unconditionally (for the current implementation - // there is no way for the importer to know that an importee does not need - // an initializer to be run). - - // Module initializers for imported modules are emitted first. - // Collect the modules that we import - SmallVector<Module *> AllImports; - // Ones that we export - for (auto I : Primary->Exports) - AllImports.push_back(I.getPointer()); - // Ones that we only import. - for (Module *M : Primary->Imports) - AllImports.push_back(M); - - SmallVector<llvm::Function *, 8> ModuleInits; - for (Module *M : AllImports) { - llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); - SmallString<256> FnName; - { - llvm::raw_svector_ostream Out(FnName); - cast<ItaniumMangleContext>(getCXXABI().getMangleContext()) - .mangleModuleInitializer(M, Out); - } - assert(!GetGlobalValue(FnName.str()) && - "We should only have one use of the initializer call"); - llvm::Function *Fn = llvm::Function::Create( - FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule()); - ModuleInits.push_back(Fn); - } - AllImports.clear(); - - // Add any initializers with specified priority; this uses the same approach - // as EmitCXXGlobalInitFunc(). - if (!PrioritizedCXXGlobalInits.empty()) { - SmallVector<llvm::Function *, 8> LocalCXXGlobalInits; - llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), - PrioritizedCXXGlobalInits.end()); - for (SmallVectorImpl<GlobalInitData>::iterator - I = PrioritizedCXXGlobalInits.begin(), - E = PrioritizedCXXGlobalInits.end(); - I != E;) { - SmallVectorImpl<GlobalInitData>::iterator PrioE = - std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp()); - - for (; I < PrioE; ++I) - ModuleInits.push_back(I->second); - } - PrioritizedCXXGlobalInits.clear(); - } - - // Now append the ones without specified priority. - for (auto F : CXXGlobalInits) - ModuleInits.push_back(F); - CXXGlobalInits.clear(); - - llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); - const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); - - // We now build the initializer for this module, which has a mangled name - // as per the Itanium ABI . The action of the initializer is guarded so that - // each init is run just once (even though a module might be imported - // multiple times via nested use). - llvm::Function *Fn; - llvm::GlobalVariable *Guard = nullptr; - { - SmallString<256> InitFnName; - llvm::raw_svector_ostream Out(InitFnName); - cast<ItaniumMangleContext>(getCXXABI().getMangleContext()) - .mangleModuleInitializer(Primary, Out); - Fn = CreateGlobalInitOrCleanUpFunction( - FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false, - llvm::GlobalVariable::ExternalLinkage); - - Guard = new llvm::GlobalVariable(getModule(), Int8Ty, /*isConstant=*/false, - llvm::GlobalVariable::InternalLinkage, - llvm::ConstantInt::get(Int8Ty, 0), - InitFnName.str() + "__in_chrg"); - } - CharUnits GuardAlign = CharUnits::One(); - Guard->setAlignment(GuardAlign.getAsAlign()); - - CodeGenFunction(*this).GenerateCXXGlobalInitFunc( - Fn, ModuleInits, ConstantAddress(Guard, Int8Ty, GuardAlign)); - // We allow for the case that a module object is added to a linked binary - // without a specific call to the the initializer. This also ensure that - // implementation partition initializers are called when the partition - // is not imported as an interface. - AddGlobalCtor(Fn); - - // See the comment in EmitCXXGlobalInitFunc about OpenCL global init - // functions. - if (getLangOpts().OpenCL) { - GenKernelArgMetadata(Fn); - Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL); - } - - assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice || - getLangOpts().GPUAllowDeviceInit); - if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) { - Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL); - Fn->addFnAttr("device-init"); - } - - ModuleInits.clear(); -} - static SmallString<128> getTransformedFileName(llvm::Module &M) { SmallString<128> FileName = llvm::sys::path::filename(M.getName()); @@ -771,26 +650,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() { while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) CXXGlobalInits.pop_back(); - // When we import C++20 modules, we must run their initializers first. - SmallVector<llvm::Function *, 8> ModuleInits; - if (CXX20ModuleInits) - for (Module *M : ImportedModules) { - llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); - SmallString<256> FnName; - { - llvm::raw_svector_ostream Out(FnName); - cast<ItaniumMangleContext>(getCXXABI().getMangleContext()) - .mangleModuleInitializer(M, Out); - } - assert(!GetGlobalValue(FnName.str()) && - "We should only have one use of the initializer call"); - llvm::Function *Fn = llvm::Function::Create( - FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule()); - ModuleInits.push_back(Fn); - } - - if (ModuleInits.empty() && CXXGlobalInits.empty() && - PrioritizedCXXGlobalInits.empty()) + if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) return; llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); @@ -816,13 +676,6 @@ CodeGenModule::EmitCXXGlobalInitFunc() { llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( FTy, "_GLOBAL__I_" + getPrioritySuffix(Priority), FI); - // Prepend the module inits to the highest priority set. - if (!ModuleInits.empty()) { - for (auto F : ModuleInits) - LocalCXXGlobalInits.push_back(F); - ModuleInits.clear(); - } - for (; I < PrioE; ++I) LocalCXXGlobalInits.push_back(I->second); @@ -832,33 +685,17 @@ CodeGenModule::EmitCXXGlobalInitFunc() { PrioritizedCXXGlobalInits.clear(); } - if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() && - CXXGlobalInits.empty()) + if (getCXXABI().useSinitAndSterm() && CXXGlobalInits.empty()) return; - for (auto F : CXXGlobalInits) - ModuleInits.push_back(F); - CXXGlobalInits.clear(); - // Include the filename in the symbol name. Including "sub_" matches gcc // and makes sure these symbols appear lexicographically behind the symbols // with priority emitted above. - llvm::Function *Fn; - if (CXX20ModuleInits && getContext().getModuleForCodeGen()) { - SmallString<256> InitFnName; - llvm::raw_svector_ostream Out(InitFnName); - cast<ItaniumMangleContext>(getCXXABI().getMangleContext()) - .mangleModuleInitializer(getContext().getModuleForCodeGen(), Out); - Fn = CreateGlobalInitOrCleanUpFunction( - FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false, - llvm::GlobalVariable::ExternalLinkage); - } else - Fn = CreateGlobalInitOrCleanUpFunction( - FTy, - llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), - FI); - - CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits); + llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( + FTy, llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), + FI); + + CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits); AddGlobalCtor(Fn); // In OpenCL global init functions must be converted to kernels in order to @@ -881,7 +718,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() { Fn->addFnAttr("device-init"); } - ModuleInits.clear(); + CXXGlobalInits.clear(); } void CodeGenModule::EmitCXXGlobalCleanUpFunc() { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e282bc8..56ed59d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -136,13 +136,6 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, GlobalsInt8PtrTy = Int8Ty->getPointerTo(DL.getDefaultGlobalsAddressSpace()); ASTAllocaAddressSpace = getTargetCodeGenInfo().getASTAllocaAddressSpace(); - // Build C++20 Module initializers. - // TODO: Add Microsoft here once we know the mangling required for the - // initializers. - CXX20ModuleInits = - LangOpts.CPlusPlusModules && getCXXABI().getMangleContext().getKind() == - ItaniumMangleContext::MK_Itanium; - RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC(); if (LangOpts.ObjC) @@ -516,18 +509,12 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO, } void CodeGenModule::Release() { - Module *Primary = getContext().getModuleForCodeGen(); - if (CXX20ModuleInits && Primary) - EmitModuleInitializers(Primary); EmitDeferred(); EmitVTablesOpportunistically(); applyGlobalValReplacements(); applyReplacements(); emitMultiVersionFunctions(); - if (CXX20ModuleInits && Primary && Primary->isInterfaceOrPartition()) - EmitCXXModuleInitFunc(Primary); - else - EmitCXXGlobalInitFunc(); + EmitCXXGlobalInitFunc(); EmitCXXGlobalCleanUpFunc(); registerGlobalDtorsWithAtExit(); EmitCXXThreadLocalInitFunc(); @@ -2504,31 +2491,6 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod, } } -void CodeGenModule::EmitModuleInitializers(clang::Module *Primary) { - // Emit the initializers in the order that sub-modules appear in the - // source, first Global Module Fragments, if present. - if (auto GMF = Primary->getGlobalModuleFragment()) { - for (Decl *D : getContext().getModuleInitializers(GMF)) { - assert(D->getKind() == Decl::Var && "GMF initializer decl is not a var?"); - EmitTopLevelDecl(D); - } - } - // Second any associated with the module, itself. - for (Decl *D : getContext().getModuleInitializers(Primary)) { - // Skip import decls, the inits for those are called explicitly. - if (D->getKind() == Decl::Import) - continue; - EmitTopLevelDecl(D); - } - // Third any associated with the Privat eMOdule Fragment, if present. - if (auto PMF = Primary->getPrivateModuleFragment()) { - for (Decl *D : getContext().getModuleInitializers(PMF)) { - assert(D->getKind() == Decl::Var && "PMF initializer decl is not a var?"); - EmitTopLevelDecl(D); - } - } -} - void CodeGenModule::EmitModuleLinkOptions() { // Collect the set of all of the modules we want to visit to emit link // options, which is essentially the imported modules and all of their @@ -2934,19 +2896,12 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) { // explicitly instantiated, so they should not be emitted eagerly. return false; } - if (const auto *VD = dyn_cast<VarDecl>(Global)) { + if (const auto *VD = dyn_cast<VarDecl>(Global)) if (Context.getInlineVariableDefinitionKind(VD) == ASTContext::InlineVariableDefinitionKind::WeakUnknown) // A definition of an inline constexpr static data member may change // linkage later if it's redeclared outside the class. return false; - if (CXX20ModuleInits && VD->getOwningModule()) { - // For CXX20, module-owned initializers need to be deferred, since it is - // not known at this point if they will be run for the current module or - // as part of the initializer for an imported one. - return false; - } - } // If OpenMP is enabled and threadprivates must be generated like TLS, delay // codegen for global variables, because they may be marked as threadprivate. if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS && @@ -6243,12 +6198,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { DI->EmitImportDecl(*Import); } - // For CXX20 we are done - we will call the module initializer for the - // imported module, and that will likewise call those for any imports it - // has. - if (CXX20ModuleInits) - break; - // Find all of the submodules and emit the module initializers. llvm::SmallPtrSet<clang::Module *, 16> Visited; SmallVector<clang::Module *, 16> Stack; diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 94ee5f8..da43b96 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -303,7 +303,7 @@ private: std::unique_ptr<CGCXXABI> ABI; llvm::LLVMContext &VMContext; std::string ModuleNameHash; - bool CXX20ModuleInits = false; + std::unique_ptr<CodeGenTBAA> TBAA; mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo; @@ -1574,9 +1574,6 @@ private: /// Emit the function that initializes C++ thread_local variables. void EmitCXXThreadLocalInitFunc(); - /// Emit the function that initializes global variables for a C++ Module. - void EmitCXXModuleInitFunc(clang::Module *Primary); - /// Emit the function that initializes C++ globals. void EmitCXXGlobalInitFunc(); @@ -1644,9 +1641,6 @@ private: /// Emit the llvm.used and llvm.compiler.used metadata. void emitLLVMUsed(); - /// For C++20 Itanium ABI, emit the initializers for the module. - void EmitModuleInitializers(clang::Module *Primary); - /// Emit the link options introduced by imported modules. void EmitModuleLinkOptions(); diff --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp index 5fca029..04b3f04 100644 --- a/clang/lib/Parse/ParseAST.cpp +++ b/clang/lib/Parse/ParseAST.cpp @@ -172,29 +172,6 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) { for (Decl *D : S.WeakTopLevelDecls()) Consumer->HandleTopLevelDecl(DeclGroupRef(D)); - // For C++20 modules, the codegen for module initializers needs to be altered - // and to be able to use a name based on the module name. - - // At this point, we should know if we are building a non-header C++20 module. - if (S.getLangOpts().CPlusPlusModules && !S.getLangOpts().IsHeaderFile && - !S.getLangOpts().CurrentModule.empty()) { - // If we are building the module from source, then the top level module - // will be here. - Module *CodegenModule = S.getCurrentModule(); - bool Interface = true; - if (CodegenModule) - // We only use module initializers for interfaces (including partition - // implementation units). - Interface = S.currentModuleIsInterface(); - else - // If we are building the module from a PCM file, then the module can be - // found here. - CodegenModule = S.getPreprocessor().getCurrentModule(); - // If neither. then .... - assert(CodegenModule && "codegen for a module, but don't know which?"); - if (Interface) - S.getASTContext().setModuleForCodeGen(CodegenModule); - } Consumer->HandleTranslationUnit(S.getASTContext()); // Finalize the template instantiation observer chain. diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index f5c24bd..e9a1ac17 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -344,16 +344,6 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, // statements, so imports are allowed. ImportState = ModuleImportState::ImportAllowed; - // For an implementation, We already made an implicit import (its interface). - // Make and return the import decl to be added to the current TU. - if (MDK == ModuleDeclKind::Implementation) { - // Make the import decl for the interface. - ImportDecl *Import = - ImportDecl::Create(Context, CurContext, ModuleLoc, Mod, Path[0].second); - // and return it to be added. - return ConvertDeclToDeclGroup(Import); - } - // FIXME: Create a ModuleDecl. return nullptr; } |