diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2024-02-23 10:59:46 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2024-02-23 11:05:15 +0800 |
commit | 2e5af56b05c2d39ab2c829bf4c13190523b67ddd (patch) | |
tree | 59c9917f61b3c1ba0c1c771a4b193050b7c09861 | |
parent | 5ccf54640a2bdb6f36f65c574feb312da7f75243 (diff) | |
download | llvm-2e5af56b05c2d39ab2c829bf4c13190523b67ddd.zip llvm-2e5af56b05c2d39ab2c829bf4c13190523b67ddd.tar.gz llvm-2e5af56b05c2d39ab2c829bf4c13190523b67ddd.tar.bz2 |
[C++20] [Modules] Allow to compile a pcm with and without -fPIC
seperately
We can compile a module unit in 2 phase compilaton:
```
clang++ -std=c++20 a.cppm --precompile -o a.pcm
clang++ -std=c++20 a.pcm -c -o a.o
```
And it is a general requirement that we need to compile a translation
unit with and without -fPIC for static and shared libraries.
But for C++20 modules with 2 phase compilation, it may be waste of time
to compile them 2 times completely. It may be fine to generate one BMI
and compile it with and without -fPIC seperately.
e.g.,
```
clang++ -std=c++20 a.cppm --precompile -o a.pcm
clang++ -std=c++20 a.pcm -c -o a.o
clang++ -std=c++20 a.pcm -c -fPIC -o a-PIC.o
```
Then we can save the time to parse a.cppm repeatedly.
-rw-r--r-- | clang/include/clang/Frontend/ASTUnit.h | 23 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CompilerInstance.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CompilerInvocation.h | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 2 | ||||
-rw-r--r-- | clang/test/Modules/compile-pcm-with-pic.cppm | 21 | ||||
-rw-r--r-- | clang/tools/c-index-test/core_main.cpp | 2 | ||||
-rw-r--r-- | clang/tools/libclang/CIndex.cpp | 2 |
8 files changed, 54 insertions, 15 deletions
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 6af712a..a2c1b25 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -691,16 +691,19 @@ public: /// lifetime is expected to extend past that of the returned ASTUnit. /// /// \returns - The initialized ASTUnit or null if the AST failed to load. - static std::unique_ptr<ASTUnit> LoadFromASTFile( - const std::string &Filename, const PCHContainerReader &PCHContainerRdr, - WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - const FileSystemOptions &FileSystemOpts, - std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls = false, - CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, - bool AllowASTWithCompilerErrors = false, - bool UserFilesAreVolatile = false, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = - llvm::vfs::getRealFileSystem()); + static std::unique_ptr<ASTUnit> + LoadFromASTFile(const std::string &Filename, + const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + const FileSystemOptions &FileSystemOpts, + std::shared_ptr<HeaderSearchOptions> HSOpts, + std::shared_ptr<LangOptions> LangOpts = nullptr, + bool OnlyLocalDecls = false, + CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None, + bool AllowASTWithCompilerErrors = false, + bool UserFilesAreVolatile = false, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = + llvm::vfs::getRealFileSystem()); private: /// Helper function for \c LoadFromCompilerInvocation() and diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index ac2f940..b97d0c6 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -311,6 +311,9 @@ public: LangOptions &getLangOpts() { return Invocation->getLangOpts(); } const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); } + std::shared_ptr<LangOptions> getLangOptsPtr() const { + return Invocation->getLangOptsPtr(); + } PreprocessorOptions &getPreprocessorOpts() { return Invocation->getPreprocessorOpts(); diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index c6528779..8fc51e6 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -271,6 +271,7 @@ public: std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() { return PPOpts; } + std::shared_ptr<LangOptions> getLangOptsPtr() { return LangOpts; } /// @} /// Create a compiler invocation from a list of input options. diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index f09a01b..3610a08 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -540,7 +540,17 @@ public: if (InitializedLanguage) return false; + // FIXME: We did similar things in ReadHeaderSearchOptions too. But such + // style is not scaling. Probably we need to invite some mechanism to + // handle such patterns generally. + auto PICLevel = LangOpt.PICLevel; + auto PIE = LangOpt.PIE; + LangOpt = LangOpts; + + LangOpt.PICLevel = PICLevel; + LangOpt.PIE = PIE; + InitializedLanguage = true; updated(); @@ -790,7 +800,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( const std::string &Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, - std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls, + std::shared_ptr<HeaderSearchOptions> HSOpts, + std::shared_ptr<LangOptions> LangOpts, bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors, bool UserFilesAreVolatile, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { std::unique_ptr<ASTUnit> AST(new ASTUnit(true)); @@ -804,7 +815,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( ConfigureDiags(Diags, *AST, CaptureDiagnostics); - AST->LangOpts = std::make_shared<LangOptions>(); + AST->LangOpts = LangOpts ? LangOpts : std::make_shared<LangOptions>(); AST->OnlyLocalDecls = OnlyLocalDecls; AST->CaptureDiagnostics = CaptureDiagnostics; AST->Diagnostics = Diags; diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index eff785b..b9fd9b8 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -689,7 +689,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile( std::string(InputFile), CI.getPCHContainerReader(), ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(), - CI.getHeaderSearchOptsPtr()); + CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr()); if (!AST) return false; diff --git a/clang/test/Modules/compile-pcm-with-pic.cppm b/clang/test/Modules/compile-pcm-with-pic.cppm new file mode 100644 index 0000000..3d818dd --- /dev/null +++ b/clang/test/Modules/compile-pcm-with-pic.cppm @@ -0,0 +1,21 @@ +// REQUIRES: x86-registered-target + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %clang_cc1 -std=c++20 %s -pic-level 2 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %s -pic-level 2 -fmodule-output=%t/m.pcm -emit-llvm -o - \ +// RUN: | FileCheck %s +// +// RUN: %clang_cc1 -std=c++20 %s -emit-module-interface -o %t/m.pcm +// RUN: %clang_cc1 -std=c++20 %t/m.pcm -pic-level 2 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++20 %t/m.pcm -emit-llvm -o - | FileCheck %s --check-prefix=NOPIC + +export module m; +export int x; +export int func() { + return x; +} + +// CHECK: ![[METADATA_NUM:[0-9]+]] = !{{{.*}}, !"PIC Level", i32 2} +// NOPIC-NOT: ![[METADATA_NUM:[0-9]+]] = !{{{.*}}, !"PIC Level", i32 2} diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp index 56bf7c9..c552466 100644 --- a/clang/tools/c-index-test/core_main.cpp +++ b/clang/tools/c-index-test/core_main.cpp @@ -276,7 +276,7 @@ static bool printSourceSymbolsFromModule(StringRef modulePath, CompilerInstance::createDiagnostics(new DiagnosticOptions()); std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile( std::string(modulePath), *pchRdr, ASTUnit::LoadASTOnly, Diags, - FileSystemOpts, HSOpts, + FileSystemOpts, HSOpts, /*LangOpts=*/nullptr, /*OnlyLocalDecls=*/true, CaptureDiagsKind::None, /*AllowASTWithCompilerErrors=*/true, /*UserFilesAreVolatile=*/false); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 4ded92c..418b152 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3890,7 +3890,7 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx, std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile( ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), ASTUnit::LoadEverything, Diags, FileSystemOpts, HSOpts, - CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All, + /*LangOpts=*/nullptr, CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All, /*AllowASTWithCompilerErrors=*/true, /*UserFilesAreVolatile=*/true); *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU)); |