From feb54b6ded123f8118fdc20620d3f657dfeab485 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 23 Oct 2014 02:01:19 +0000 Subject: [PATCH] Refactor implementation of 'exclude header'. This was not a real header role, and was never exposed to clients of ModuleMap. Remove the enumeration value for it and track it as marking the header as 'known' rather than creating an extra KnownHeader entry that *every single* client ignores. llvm-svn: 220460 --- clang/include/clang/Lex/ModuleMap.h | 9 +++--- clang/lib/Lex/ModuleMap.cpp | 32 +++++++++---------- clang/test/Modules/Inputs/declare-use/m.h | 8 +++++ clang/test/Modules/Inputs/declare-use/m2.h | 1 + .../Modules/Inputs/declare-use/module.map | 5 +++ clang/test/Modules/textual-headers.cpp | 9 +++++- clang/tools/libclang/CIndex.cpp | 6 +--- 7 files changed, 44 insertions(+), 26 deletions(-) create mode 100644 clang/test/Modules/Inputs/declare-use/m.h create mode 100644 clang/test/Modules/Inputs/declare-use/m2.h diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index 5eda274bcfec..2742b0f6c39b 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -74,8 +74,6 @@ public: /// \brief This header is part of the module (for layering purposes) but /// should be textually included. TextualHeader, - /// \brief This header is explicitly excluded from the module. - ExcludedHeader // Caution: Adding an enumerator needs other changes. // Adjust the number of bits for KnownHeader::Storage. // Adjust the bitfield HeaderFileInfo::HeaderRole size. @@ -99,8 +97,8 @@ public: ModuleHeaderRole getRole() const { return Storage.getInt(); } /// \brief Whether this header is available in the module. - bool isAvailable() const { - return getRole() != ExcludedHeader && getModule()->isAvailable(); + bool isAvailable() const { + return getModule()->isAvailable(); } // \brief Whether this known header is valid (i.e., it has an @@ -444,6 +442,9 @@ public: void addHeader(Module *Mod, const FileEntry *Header, ModuleHeaderRole Role); + /// \brief Marks this header as being excluded from the given module. + void excludeHeader(Module *Mod, const FileEntry *Header); + /// \brief Parse the given module map file, and record any modules we /// encounter. /// diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 865b62a6a670..c191e0199a96 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -253,12 +253,6 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, HeadersMap::iterator Known = findKnownHeader(File); if (Known != Headers.end()) { for (const KnownHeader &Header : Known->second) { - // Excluded headers don't really belong to a module. - if (Header.getRole() == ModuleMap::ExcludedHeader) { - Excluded = true; - continue; - } - // If 'File' is part of 'RequestingModule' we can definitely include it. if (Header.getModule() == RequestingModule) return; @@ -281,6 +275,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule, // We have found a module that we can happily use. return; } + + Excluded = true; } // We have found a header, but it is private. @@ -332,10 +328,6 @@ ModuleMap::findModuleForHeader(const FileEntry *File, for (SmallVectorImpl::iterator I = Known->second.begin(), E = Known->second.end(); I != E; ++I) { - // Cannot use a module if the header is excluded in it. - if (I->getRole() == ModuleMap::ExcludedHeader) - continue; - // Cannot use a module if it is unavailable. if (!I->getModule()->isAvailable()) continue; @@ -791,9 +783,7 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) { void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, ModuleHeaderRole Role) { - if (Role == ExcludedHeader) { - Mod->ExcludedHeaders.push_back(Header); - } else if (Role == TextualHeader) { + if (Role == TextualHeader) { Mod->TextualHeaders.push_back(Header); } else { if (Role == PrivateHeader) @@ -806,6 +796,16 @@ void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, Headers[Header].push_back(KnownHeader(Mod, Role)); } +void ModuleMap::excludeHeader(Module *Mod, const FileEntry *Header) { + Mod->ExcludedHeaders.push_back(Header); + + // Add this as a known header so we won't implicitly add it to any + // umbrella directory module. + // FIXME: Should we only exclude it from umbrella modules within the + // specified module? + (void) Headers[Header]; +} + const FileEntry * ModuleMap::getContainingModuleMapFile(const Module *Module) const { if (Module->DefinitionLoc.isInvalid()) @@ -1767,12 +1767,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, // Record this umbrella header. Map.setUmbrellaHeader(ActiveModule, File); } + } else if (LeadingToken == MMToken::ExcludeKeyword) { + Map.excludeHeader(ActiveModule, File); } else { // Record this header. ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; - if (LeadingToken == MMToken::ExcludeKeyword) - Role = ModuleMap::ExcludedHeader; - else if (LeadingToken == MMToken::PrivateKeyword) + if (LeadingToken == MMToken::PrivateKeyword) Role = ModuleMap::PrivateHeader; else if (LeadingToken == MMToken::TextualKeyword) Role = ModuleMap::TextualHeader; diff --git a/clang/test/Modules/Inputs/declare-use/m.h b/clang/test/Modules/Inputs/declare-use/m.h new file mode 100644 index 000000000000..e9089ab725d5 --- /dev/null +++ b/clang/test/Modules/Inputs/declare-use/m.h @@ -0,0 +1,8 @@ +#ifdef GIMME_AN_M + +#ifndef M_H +#define M_H +const int m = 42; +#endif + +#endif diff --git a/clang/test/Modules/Inputs/declare-use/m2.h b/clang/test/Modules/Inputs/declare-use/m2.h new file mode 100644 index 000000000000..9e72835c3bce --- /dev/null +++ b/clang/test/Modules/Inputs/declare-use/m2.h @@ -0,0 +1 @@ +#include "m.h" diff --git a/clang/test/Modules/Inputs/declare-use/module.map b/clang/test/Modules/Inputs/declare-use/module.map index c6c6c951bd01..ae8615278aca 100644 --- a/clang/test/Modules/Inputs/declare-use/module.map +++ b/clang/test/Modules/Inputs/declare-use/module.map @@ -61,5 +61,10 @@ module XL { textual header "l.h" } +module XM { + private textual header "m.h" + textual header "m2.h" +} + module XS { } diff --git a/clang/test/Modules/textual-headers.cpp b/clang/test/Modules/textual-headers.cpp index d1be8ad0321a..54078999bd5e 100644 --- a/clang/test/Modules/textual-headers.cpp +++ b/clang/test/Modules/textual-headers.cpp @@ -1,6 +1,6 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodule-maps -fmodules-cache-path=%t -fmodules-strict-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-strict-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-strict-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify -fmodules-no-error-recovery #define GIMME_A_K #include "k.h" @@ -8,4 +8,11 @@ #define GIMME_AN_L #include "l.h" // expected-error {{module XG does not depend on a module exporting 'l.h'}} +#include "m2.h" // expected-error {{module XG does not depend on a module exporting 'm2.h'}} +const int use_m = m; + +#define GIMME_AN_M +#include "m.h" +const int use_m_2 = m; + const int g = k + l; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index e96bb1cb895d..084e9d9cc4aa 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -6650,11 +6650,7 @@ CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) { HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo(); ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE); - if (Module *Mod = Header.getModule()) { - if (Header.getRole() != ModuleMap::ExcludedHeader) - return Mod; - } - return nullptr; + return Header.getModule(); } CXFile clang_Module_getASTFile(CXModule CXMod) {