aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2024-02-23 10:59:46 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2024-02-23 11:05:15 +0800
commit2e5af56b05c2d39ab2c829bf4c13190523b67ddd (patch)
tree59c9917f61b3c1ba0c1c771a4b193050b7c09861
parent5ccf54640a2bdb6f36f65c574feb312da7f75243 (diff)
downloadllvm-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.h23
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h3
-rw-r--r--clang/include/clang/Frontend/CompilerInvocation.h1
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp15
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp2
-rw-r--r--clang/test/Modules/compile-pcm-with-pic.cppm21
-rw-r--r--clang/tools/c-index-test/core_main.cpp2
-rw-r--r--clang/tools/libclang/CIndex.cpp2
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));