Skip to content

[Preprocessor] Do not expand macros if the input is already preprocessed #137665

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion clang/include/clang/Frontend/FrontendAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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().SetEnableMacroExpansion(false);
return true;
}

Expand All @@ -98,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.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,8 @@ class Preprocessor {
MacroExpansionInDirectivesOverride = true;
}

void SetEnableMacroExpansion(bool Enable) { DisableMacroExpansion = !Enable; }

/// Peeks ahead N tokens and returns that token without consuming any
/// tokens.
///
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,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>>
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Frontend/Rewrite/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,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) {
Expand Down Expand Up @@ -299,7 +300,7 @@ bool RewriteIncludesAction::BeginSourceFileAction(CompilerInstance &CI) {
std::make_unique<RewriteImportsListener>(CI, OutputStream));
}

return true;
return PreprocessorFrontendAction::BeginSourceFileAction(CI);
}

void RewriteIncludesAction::ExecuteAction() {
Expand Down
59 changes: 55 additions & 4 deletions clang/test/Modules/initializers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions clang/test/Preprocessor/preprocess-cpp-output.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_cc1 -E -x c %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() {
return 4;
}