From 40fb0b9d860602604ba73e3df69ea5002ce67caa Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 18 Aug 2016 01:16:55 +0000 Subject: [PATCH] PR28438: Update the information on an identifier with local definitions before trying to write out its macro graph, in case we imported a module that added another module macro between the most recent local definition and the end of the module. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@279024 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/Preprocessor.h | 6 ++++++ lib/Lex/Preprocessor.cpp | 7 ++++++- test/Modules/Inputs/PR28438/a.h | 1 + test/Modules/Inputs/PR28438/b1.h | 2 ++ test/Modules/Inputs/PR28438/b2.h | 0 test/Modules/Inputs/PR28438/module.modulemap | 2 ++ test/Modules/pr28438.cpp | 9 +++++++++ 7 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 test/Modules/Inputs/PR28438/a.h create mode 100644 test/Modules/Inputs/PR28438/b1.h create mode 100644 test/Modules/Inputs/PR28438/b2.h create mode 100644 test/Modules/Inputs/PR28438/module.modulemap create mode 100644 test/Modules/pr28438.cpp diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 000df6647f..66ff490de1 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -398,6 +398,8 @@ class Preprocessor : public RefCountedBase { ModuleMacroInfo *getModuleInfo(Preprocessor &PP, const IdentifierInfo *II) const { + if (II->isOutOfDate()) + PP.updateOutOfDateIdentifier(const_cast(*II)); // FIXME: Find a spare bit on IdentifierInfo and store a // HasModuleMacros flag. if (!II->hasMacroDefinition() || @@ -653,6 +655,8 @@ class Preprocessor : public RefCountedBase { }; DeserializedMacroInfoChain *DeserialMIChainHead; + void updateOutOfDateIdentifier(IdentifierInfo &II) const; + public: Preprocessor(IntrusiveRefCntPtr PPOpts, DiagnosticsEngine &diags, LangOptions &opts, @@ -900,6 +904,8 @@ public: /// \brief Get the list of leaf (non-overridden) module macros for a name. ArrayRef getLeafModuleMacros(const IdentifierInfo *II) const { + if (II->isOutOfDate()) + updateOutOfDateIdentifier(const_cast(*II)); auto I = LeafModuleMacros.find(II); if (I != LeafModuleMacros.end()) return I->second; diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index f0d6872546..7303937382 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -618,6 +618,11 @@ static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II, "Keyword not known to come from a newer Standard or proposed Standard"); } +void Preprocessor::updateOutOfDateIdentifier(IdentifierInfo &II) const { + assert(II.isOutOfDate() && "not out of date"); + getExternalSource()->updateOutOfDateIdentifier(II); +} + /// HandleIdentifier - This callback is invoked when the lexer reads an /// identifier. This callback looks up the identifier in the map and/or /// potentially macro expands it or turns it into a named token (like 'for'). @@ -642,7 +647,7 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { if (&II == Ident__VA_ARGS__) CurrentIsPoisoned = Ident__VA_ARGS__->isPoisoned(); - ExternalSource->updateOutOfDateIdentifier(II); + updateOutOfDateIdentifier(II); Identifier.setKind(II.getTokenID()); if (&II == Ident__VA_ARGS__) diff --git a/test/Modules/Inputs/PR28438/a.h b/test/Modules/Inputs/PR28438/a.h new file mode 100644 index 0000000000..a7e26ac6cd --- /dev/null +++ b/test/Modules/Inputs/PR28438/a.h @@ -0,0 +1 @@ +#define FOO diff --git a/test/Modules/Inputs/PR28438/b1.h b/test/Modules/Inputs/PR28438/b1.h new file mode 100644 index 0000000000..262976e357 --- /dev/null +++ b/test/Modules/Inputs/PR28438/b1.h @@ -0,0 +1,2 @@ +#define FOO +#include "a.h" diff --git a/test/Modules/Inputs/PR28438/b2.h b/test/Modules/Inputs/PR28438/b2.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Modules/Inputs/PR28438/module.modulemap b/test/Modules/Inputs/PR28438/module.modulemap new file mode 100644 index 0000000000..cb77d47b6c --- /dev/null +++ b/test/Modules/Inputs/PR28438/module.modulemap @@ -0,0 +1,2 @@ +module A { header "a.h" export * } +module B { module B1 { header "b1.h" export * } module B2 { header "b2.h" export * } } diff --git a/test/Modules/pr28438.cpp b/test/Modules/pr28438.cpp new file mode 100644 index 0000000000..b8b9077046 --- /dev/null +++ b/test/Modules/pr28438.cpp @@ -0,0 +1,9 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fsyntax-only -verify %s -fmodules -fmodules-cache-path=%t -I%S/Inputs/PR28438 -fimplicit-module-maps + +#include "a.h" +#include "b2.h" + +#pragma clang __debug macro FOO + +FOO // xpected-no-diagnostics -- 2.40.0