PCH + module: make sure we write out macros associated with builtin identifiers.

When we import a module that defines a builtin identifier from prefix header and
precompile the prefix header, the macro information related to the identifier
is lost.

If we don't precompile the prefix header, the source file can still see the
macro information. The reason is that we write out the identifier in the pch
but not the macro information since the macro is not defined locally.

This is related to r251565. In that commit, if we read a builtin identifier from
a module that wasn't "interesting" to that module, we will still write it out to
a PCH that imports that module.

The fix is to write exported module macros for PCH as well.

rdar://24666630

Differential Revision: http://reviews.llvm.org/D20383

llvm-svn: 271310
This commit is contained in:
Manman Ren 2016-05-31 18:19:32 +00:00
parent 3b3f490f9c
commit 33d8029589
5 changed files with 41 additions and 20 deletions

View File

@ -2187,30 +2187,29 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
// Write out any exported module macros.
bool EmittedModuleMacros = false;
if (IsModule) {
auto Leafs = PP.getLeafModuleMacros(Name);
SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
llvm::DenseMap<ModuleMacro*, unsigned> Visits;
while (!Worklist.empty()) {
auto *Macro = Worklist.pop_back_val();
// We write out exported module macros for PCH as well.
auto Leafs = PP.getLeafModuleMacros(Name);
SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
llvm::DenseMap<ModuleMacro*, unsigned> Visits;
while (!Worklist.empty()) {
auto *Macro = Worklist.pop_back_val();
// Emit a record indicating this submodule exports this macro.
ModuleMacroRecord.push_back(
getSubmoduleID(Macro->getOwningModule()));
ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
for (auto *M : Macro->overrides())
ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
// Emit a record indicating this submodule exports this macro.
ModuleMacroRecord.push_back(
getSubmoduleID(Macro->getOwningModule()));
ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
for (auto *M : Macro->overrides())
ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
ModuleMacroRecord.clear();
Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
ModuleMacroRecord.clear();
// Enqueue overridden macros once we've visited all their ancestors.
for (auto *M : Macro->overrides())
if (++Visits[M] == M->getNumOverridingMacros())
Worklist.push_back(M);
// Enqueue overridden macros once we've visited all their ancestors.
for (auto *M : Macro->overrides())
if (++Visits[M] == M->getNumOverridingMacros())
Worklist.push_back(M);
EmittedModuleMacros = true;
}
EmittedModuleMacros = true;
}
if (Record.empty() && !EmittedModuleMacros)

View File

@ -0,0 +1,6 @@
#undef fabs
#define fabs(x) (x)
#undef my_fabs
#define my_fabs(x) (x)

View File

@ -414,3 +414,7 @@ module MethodPoolString2 {
}
module Empty {}
module MacroFabs1 {
header "MacroFabs1.h"
}

View File

@ -0,0 +1,3 @@
@import MacroFabs1;

View File

@ -0,0 +1,9 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-with-macro.pch
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
// expected-no-diagnostics
int test(int x) {
return my_fabs(x) + fabs(x);
}