https://github.com/jmmartinez updated https://github.com/llvm/llvm-project/pull/137665
From f0d1f76540ca2121a7b70c71c7403a7d45584482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Mon, 28 Apr 2025 17:05:46 +0200 Subject: [PATCH 1/8] Pre-commit test: [Preprocessor] Do not expand macros if the input is already preprocessed --- clang/test/Preprocessor/preprocess-cpp-output.c | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 clang/test/Preprocessor/preprocess-cpp-output.c diff --git a/clang/test/Preprocessor/preprocess-cpp-output.c b/clang/test/Preprocessor/preprocess-cpp-output.c new file mode 100644 index 0000000000000..59ff057e9b871 --- /dev/null +++ b/clang/test/Preprocessor/preprocess-cpp-output.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -E -x c %s | FileCheck %s --check-prefixes=EXPANDED +// RUN: %clang_cc1 -E -x cpp-output %s | FileCheck %s --check-prefixes=EXPANDED + +// EXPANDED: void __attribute__((__attribute__((always_inline)))) foo() + +#define always_inline __attribute__((always_inline)) +void __attribute__((always_inline)) foo() { + return 4; +} From 3bd55452d3528b76c5d27d6f6e2a021aff2b9aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Tue, 13 May 2025 15:03:46 +0200 Subject: [PATCH 2/8] [Modules] initializers.cpp test fix The module contents should not contain preprocessor directives. The contents should be already preprocessed. Duplicate the modules instead to propose 2 versions: one with the namespace ns and one without. --- clang/test/Modules/initializers.cpp | 59 +++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/clang/test/Modules/initializers.cpp b/clang/test/Modules/initializers.cpp index dcd9b08ec6f7a..e1f826fbc09f3 100644 --- a/clang/test/Modules/initializers.cpp +++ b/clang/test/Modules/initializers.cpp @@ -48,6 +48,7 @@ // instantiation for v<int> in one of the two headers, because we will only // parse one of the two get() functions. +#ifdef NS #pragma clang module build m module m { module a { @@ -60,9 +61,7 @@ module m { #pragma clang module begin m.a inline int non_trivial() { return 3; } -#ifdef NS namespace ns { -#endif int a = non_trivial(); inline int b = non_trivial(); @@ -102,12 +101,64 @@ inline void use(bool b, ...) { X<int>::e<int>, X<int>::f<int>, X<int>::g<int>, X<int>::h<int>); } -#ifdef NS } -#endif #pragma clang module end #pragma clang module endbuild +#else +#pragma clang module build m +module m { + module a { + header "foo.h" { size 123 mtime 456789 } + } + module b {} +} + +#pragma clang module contents +#pragma clang module begin m.a +inline int non_trivial() { return 3; } + +int a = non_trivial(); +inline int b = non_trivial(); +thread_local int c = non_trivial(); +inline thread_local int d = non_trivial(); + +template<typename U> int e = non_trivial(); +template<typename U> inline int f = non_trivial(); +template<typename U> thread_local int g = non_trivial(); +template<typename U> inline thread_local int h = non_trivial(); + +inline int unused = 123; // should not be emitted + +template<typename T> struct X { + static int a; + static inline int b = non_trivial(); + static thread_local int c; + static inline thread_local int d = non_trivial(); + + template<typename U> static int e; + template<typename U> static inline int f = non_trivial(); + template<typename U> static thread_local int g; + template<typename U> static inline thread_local int h = non_trivial(); + + static inline int unused = 123; // should not be emitted +}; + +template<typename T> int X<T>::a = non_trivial(); +template<typename T> thread_local int X<T>::c = non_trivial(); +template<typename T> template<typename U> int X<T>::e = non_trivial(); +template<typename T> template<typename U> thread_local int X<T>::g = non_trivial(); + +inline void use(bool b, ...) { + if (b) return; + use(true, e<int>, f<int>, g<int>, h<int>, + X<int>::a, X<int>::b, X<int>::c, X<int>::d, + X<int>::e<int>, X<int>::f<int>, X<int>::g<int>, X<int>::h<int>); +} + +#pragma clang module end +#pragma clang module endbuild +#endif #if IMPORT == 1 // Import the module and the m.a submodule; runs the ordered initializers and From 75b7fd4a9e3fb556e53fbb858ea7890622ae64da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Tue, 22 Apr 2025 18:40:37 +0200 Subject: [PATCH 3/8] [Preprocessor] Do not expand macros if the input is already preprocessed --- clang/include/clang/Lex/Preprocessor.h | 5 +++++ clang/lib/Frontend/InitPreprocessor.cpp | 7 +++++++ clang/test/Preprocessor/preprocess-cpp-output.c | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 78be2bd64d61c..40ccc4f4b0d40 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1837,6 +1837,11 @@ class Preprocessor { MacroExpansionInDirectivesOverride = true; } + void SetDisableMacroExpansion() { + DisableMacroExpansion = true; + MacroExpansionInDirectivesOverride = false; + } + /// Peeks ahead N tokens and returns that token without consuming any /// tokens. /// diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index f64613fb4a6cb..396ea842e4e4f 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1558,6 +1558,13 @@ void clang::InitializePreprocessor(Preprocessor &PP, const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts, const CodeGenOptions &CodeGenOpts) { + + if (all_of(FEOpts.Inputs, + [](const FrontendInputFile &FI) { return FI.isPreprocessed(); })) { + PP.SetDisableMacroExpansion(); + return; + } + const LangOptions &LangOpts = PP.getLangOpts(); std::string PredefineBuffer; PredefineBuffer.reserve(4080); diff --git a/clang/test/Preprocessor/preprocess-cpp-output.c b/clang/test/Preprocessor/preprocess-cpp-output.c index 59ff057e9b871..2c180601e30ac 100644 --- a/clang/test/Preprocessor/preprocess-cpp-output.c +++ b/clang/test/Preprocessor/preprocess-cpp-output.c @@ -1,7 +1,8 @@ // RUN: %clang_cc1 -E -x c %s | FileCheck %s --check-prefixes=EXPANDED -// RUN: %clang_cc1 -E -x cpp-output %s | FileCheck %s --check-prefixes=EXPANDED +// RUN: %clang_cc1 -E -x cpp-output %s | FileCheck %s --check-prefixes=NOT-EXPANDED // EXPANDED: void __attribute__((__attribute__((always_inline)))) foo() +// NOT-EXPANDED: void __attribute__((always_inline)) foo() #define always_inline __attribute__((always_inline)) void __attribute__((always_inline)) foo() { From 3149502db55ff1403102dea22e947c377e5c5989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Thu, 22 May 2025 16:55:40 +0200 Subject: [PATCH 4/8] [Review] Disable macro expansion in BeginSourceFileAction --- clang/include/clang/Frontend/FrontendAction.h | 2 ++ clang/lib/Frontend/InitPreprocessor.cpp | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index 718684a67771a..40a9389bbf81a 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -84,6 +84,8 @@ class FrontendAction { /// \return True on success; on failure ExecutionAction() and /// EndSourceFileAction() will not be called. virtual bool BeginSourceFileAction(CompilerInstance &CI) { + if (CurrentInput.isPreprocessed()) + CI.getPreprocessor().SetDisableMacroExpansion(); return true; } diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 396ea842e4e4f..f64613fb4a6cb 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -1558,13 +1558,6 @@ void clang::InitializePreprocessor(Preprocessor &PP, const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts, const CodeGenOptions &CodeGenOpts) { - - if (all_of(FEOpts.Inputs, - [](const FrontendInputFile &FI) { return FI.isPreprocessed(); })) { - PP.SetDisableMacroExpansion(); - return; - } - const LangOptions &LangOpts = PP.getLangOpts(); std::string PredefineBuffer; PredefineBuffer.reserve(4080); From 913808467bbf9548050e3268e105b9cc68b9bb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Mon, 26 May 2025 15:26:30 +0200 Subject: [PATCH 5/8] BeginSourceFileAction/EndSourceFileAction invoke the base-class's method An exception for this is the WrapperFrontendAction which cover this through the fowraded call to WrappedAction->BeginSourceFileAction/EndSourcefileAction --- clang/lib/CodeGen/CodeGenAction.cpp | 4 +++- clang/lib/Frontend/FrontendActions.cpp | 2 +- clang/lib/Frontend/Rewrite/FrontendActions.cpp | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 5493cc92bd8b0..5fc3c601a19f4 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -908,6 +908,8 @@ bool CodeGenAction::loadLinkModules(CompilerInstance &CI) { bool CodeGenAction::hasIRSupport() const { return true; } void CodeGenAction::EndSourceFileAction() { + ASTFrontendAction::EndSourceFileAction(); + // If the consumer creation failed, do nothing. if (!getCompilerInstance().hasASTConsumer()) return; @@ -932,7 +934,7 @@ CodeGenerator *CodeGenAction::getCodeGenerator() const { bool CodeGenAction::BeginSourceFileAction(CompilerInstance &CI) { if (CI.getFrontendOpts().GenReducedBMI) CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface); - return true; + return ASTFrontendAction::BeginSourceFileAction(CI); } static std::unique_ptr<raw_pwrite_stream> diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index c0ab708d8b844..901cf92c73c57 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -181,7 +181,7 @@ bool GeneratePCHAction::shouldEraseOutputFiles() { bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) { CI.getLangOpts().CompilingPCH = true; - return true; + return ASTFrontendAction::BeginSourceFileAction(CI); } std::vector<std::unique_ptr<ASTConsumer>> diff --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 84e7a4f3f12d9..6c9c9d5b5c8d3 100644 --- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -103,12 +103,13 @@ bool FixItAction::BeginSourceFileAction(CompilerInstance &CI) { } Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), CI.getLangOpts(), FixItOpts.get())); - return true; + return ASTFrontendAction::BeginSourceFileAction(CI); } void FixItAction::EndSourceFileAction() { // Otherwise rewrite all files. Rewriter->WriteFixedFiles(); + ASTFrontendAction::EndSourceFileAction(); } bool FixItRecompile::BeginInvocation(CompilerInstance &CI) { @@ -298,7 +299,7 @@ bool RewriteIncludesAction::BeginSourceFileAction(CompilerInstance &CI) { std::make_unique<RewriteImportsListener>(CI, OutputStream)); } - return true; + return PreprocessorFrontendAction::BeginSourceFileAction(CI); } void RewriteIncludesAction::ExecuteAction() { From 0dc15b1a04222d0b3441f33767cf95d9ca99ad25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Mon, 26 May 2025 16:48:12 +0200 Subject: [PATCH 6/8] [Review] Disable and Restore the Preprocessor's macro expansion in FrontendAction's BeginSourceFileAction and EndSourceFileAction --- clang/include/clang/Frontend/FrontendAction.h | 8 ++++++-- clang/include/clang/Lex/Preprocessor.h | 5 +---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index 40a9389bbf81a..66585dbacbb36 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -85,7 +85,7 @@ class FrontendAction { /// EndSourceFileAction() will not be called. virtual bool BeginSourceFileAction(CompilerInstance &CI) { if (CurrentInput.isPreprocessed()) - CI.getPreprocessor().SetDisableMacroExpansion(); + CI.getPreprocessor().SetEnableMacroExpansion(false); return true; } @@ -100,7 +100,11 @@ class FrontendAction { /// /// This is guaranteed to only be called following a successful call to /// BeginSourceFileAction (and BeginSourceFile). - virtual void EndSourceFileAction() {} + virtual void EndSourceFileAction() { + if (CurrentInput.isPreprocessed()) + // reset the preprocessor macro expansion to the default + getCompilerInstance().getPreprocessor().SetEnableMacroExpansion(true); + } /// Callback at the end of processing a single input, to determine /// if the output files should be erased or not. diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 40ccc4f4b0d40..b9cb48a0f0a1d 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1837,10 +1837,7 @@ class Preprocessor { MacroExpansionInDirectivesOverride = true; } - void SetDisableMacroExpansion() { - DisableMacroExpansion = true; - MacroExpansionInDirectivesOverride = false; - } + void SetEnableMacroExpansion(bool Enable) { DisableMacroExpansion = !Enable; } /// Peeks ahead N tokens and returns that token without consuming any /// tokens. From 279487b66ee13852960f4d07243ae940fb6aed8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Wed, 11 Jun 2025 11:05:50 +0200 Subject: [PATCH 7/8] Pre-Commit test: [Clang][Preprocessor] Enable macro expansion **only** in directives when parsing preprocessed sources --- .../preprocess-pragma-cpp-output.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 clang/test/Preprocessor/preprocess-pragma-cpp-output.c diff --git a/clang/test/Preprocessor/preprocess-pragma-cpp-output.c b/clang/test/Preprocessor/preprocess-pragma-cpp-output.c new file mode 100644 index 0000000000000..271372b2259d5 --- /dev/null +++ b/clang/test/Preprocessor/preprocess-pragma-cpp-output.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -E -x c %s | FileCheck %s +// RUN: %clang_cc1 -x c -fsyntax-only %s -verify +// expected-no-diagnostics +// RUN: %clang_cc1 -x cpp-output -fsyntax-only -verify=fail %s + +// The preprocessor does not expand macro-identifiers in #pragma directives. +// When we preprocess & parse the code, clang expands the macros in directives. +// When we parse already preprocessed code, clang still has to expand the +// macros in the directives. +// This means that we're not always able to parse the preprocessor's output +// without preserving the definitions (-dD). + +#define FACTOR 4 + +void foo() { + // CHECK: #pragma unroll FACTOR + #pragma unroll FACTOR // fail-error{{use of undeclared identifier}} + for(;;) { + } + return; +} From 2298cdc4399ce0626cdef26037be61539ef0e3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Martinez=20Caama=C3=B1o?= <juama...@amd.com> Date: Wed, 11 Jun 2025 10:40:26 +0200 Subject: [PATCH 8/8] [Clang][Preprocessor] Enable macro expansion **only** in directives when parsing preprocessed sources The preprocessor does not expand macro-identifiers in #pragma directives. When we preprocess & parse the code, clang expands the macros in the directives. When we parse already preprocessed code, clang still has to expand the macros in the directives. This also means that we're not always able to parse the preprocessor's output without preserving the definitions (-dD). --- clang/include/clang/Frontend/FrontendAction.h | 4 ++-- clang/include/clang/Lex/Preprocessor.h | 4 +++- clang/test/Preprocessor/preprocess-pragma-cpp-output.c | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index 66585dbacbb36..8f0bff15e47fa 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -85,7 +85,7 @@ class FrontendAction { /// EndSourceFileAction() will not be called. virtual bool BeginSourceFileAction(CompilerInstance &CI) { if (CurrentInput.isPreprocessed()) - CI.getPreprocessor().SetEnableMacroExpansion(false); + CI.getPreprocessor().SetMacroExpansionOnlyInDirectives(); return true; } @@ -103,7 +103,7 @@ class FrontendAction { virtual void EndSourceFileAction() { if (CurrentInput.isPreprocessed()) // reset the preprocessor macro expansion to the default - getCompilerInstance().getPreprocessor().SetEnableMacroExpansion(true); + getCompilerInstance().getPreprocessor().SetEnableMacroExpansion(); } /// Callback at the end of processing a single input, to determine diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index b9cb48a0f0a1d..63079be3b4c0d 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1837,7 +1837,9 @@ class Preprocessor { MacroExpansionInDirectivesOverride = true; } - void SetEnableMacroExpansion(bool Enable) { DisableMacroExpansion = !Enable; } + void SetEnableMacroExpansion() { + DisableMacroExpansion = MacroExpansionInDirectivesOverride = false; + } /// Peeks ahead N tokens and returns that token without consuming any /// tokens. diff --git a/clang/test/Preprocessor/preprocess-pragma-cpp-output.c b/clang/test/Preprocessor/preprocess-pragma-cpp-output.c index 271372b2259d5..d5389374c33c5 100644 --- a/clang/test/Preprocessor/preprocess-pragma-cpp-output.c +++ b/clang/test/Preprocessor/preprocess-pragma-cpp-output.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -E -x c %s | FileCheck %s // RUN: %clang_cc1 -x c -fsyntax-only %s -verify +// RUN: %clang_cc1 -x cpp-output -fsyntax-only -verify %s // expected-no-diagnostics -// RUN: %clang_cc1 -x cpp-output -fsyntax-only -verify=fail %s // The preprocessor does not expand macro-identifiers in #pragma directives. // When we preprocess & parse the code, clang expands the macros in directives. @@ -14,7 +14,7 @@ void foo() { // CHECK: #pragma unroll FACTOR - #pragma unroll FACTOR // fail-error{{use of undeclared identifier}} + #pragma unroll FACTOR for(;;) { } return; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits