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
This commit is contained in:
Richard Smith 2014-10-23 02:01:19 +00:00
parent 7db296eba5
commit feb54b6ded
7 changed files with 44 additions and 26 deletions

View File

@ -74,8 +74,6 @@ public:
/// \brief This header is part of the module (for layering purposes) but /// \brief This header is part of the module (for layering purposes) but
/// should be textually included. /// should be textually included.
TextualHeader, TextualHeader,
/// \brief This header is explicitly excluded from the module.
ExcludedHeader
// Caution: Adding an enumerator needs other changes. // Caution: Adding an enumerator needs other changes.
// Adjust the number of bits for KnownHeader::Storage. // Adjust the number of bits for KnownHeader::Storage.
// Adjust the bitfield HeaderFileInfo::HeaderRole size. // Adjust the bitfield HeaderFileInfo::HeaderRole size.
@ -99,8 +97,8 @@ public:
ModuleHeaderRole getRole() const { return Storage.getInt(); } ModuleHeaderRole getRole() const { return Storage.getInt(); }
/// \brief Whether this header is available in the module. /// \brief Whether this header is available in the module.
bool isAvailable() const { bool isAvailable() const {
return getRole() != ExcludedHeader && getModule()->isAvailable(); return getModule()->isAvailable();
} }
// \brief Whether this known header is valid (i.e., it has an // \brief Whether this known header is valid (i.e., it has an
@ -444,6 +442,9 @@ public:
void addHeader(Module *Mod, const FileEntry *Header, void addHeader(Module *Mod, const FileEntry *Header,
ModuleHeaderRole Role); 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 /// \brief Parse the given module map file, and record any modules we
/// encounter. /// encounter.
/// ///

View File

@ -253,12 +253,6 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
HeadersMap::iterator Known = findKnownHeader(File); HeadersMap::iterator Known = findKnownHeader(File);
if (Known != Headers.end()) { if (Known != Headers.end()) {
for (const KnownHeader &Header : Known->second) { 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 'File' is part of 'RequestingModule' we can definitely include it.
if (Header.getModule() == RequestingModule) if (Header.getModule() == RequestingModule)
return; return;
@ -281,6 +275,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// We have found a module that we can happily use. // We have found a module that we can happily use.
return; return;
} }
Excluded = true;
} }
// We have found a header, but it is private. // We have found a header, but it is private.
@ -332,10 +328,6 @@ ModuleMap::findModuleForHeader(const FileEntry *File,
for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
E = Known->second.end(); E = Known->second.end();
I != E; ++I) { 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. // Cannot use a module if it is unavailable.
if (!I->getModule()->isAvailable()) if (!I->getModule()->isAvailable())
continue; continue;
@ -791,9 +783,7 @@ void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
ModuleHeaderRole Role) { ModuleHeaderRole Role) {
if (Role == ExcludedHeader) { if (Role == TextualHeader) {
Mod->ExcludedHeaders.push_back(Header);
} else if (Role == TextualHeader) {
Mod->TextualHeaders.push_back(Header); Mod->TextualHeaders.push_back(Header);
} else { } else {
if (Role == PrivateHeader) if (Role == PrivateHeader)
@ -806,6 +796,16 @@ void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
Headers[Header].push_back(KnownHeader(Mod, Role)); 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 * const FileEntry *
ModuleMap::getContainingModuleMapFile(const Module *Module) const { ModuleMap::getContainingModuleMapFile(const Module *Module) const {
if (Module->DefinitionLoc.isInvalid()) if (Module->DefinitionLoc.isInvalid())
@ -1767,12 +1767,12 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// Record this umbrella header. // Record this umbrella header.
Map.setUmbrellaHeader(ActiveModule, File); Map.setUmbrellaHeader(ActiveModule, File);
} }
} else if (LeadingToken == MMToken::ExcludeKeyword) {
Map.excludeHeader(ActiveModule, File);
} else { } else {
// Record this header. // Record this header.
ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader; ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
if (LeadingToken == MMToken::ExcludeKeyword) if (LeadingToken == MMToken::PrivateKeyword)
Role = ModuleMap::ExcludedHeader;
else if (LeadingToken == MMToken::PrivateKeyword)
Role = ModuleMap::PrivateHeader; Role = ModuleMap::PrivateHeader;
else if (LeadingToken == MMToken::TextualKeyword) else if (LeadingToken == MMToken::TextualKeyword)
Role = ModuleMap::TextualHeader; Role = ModuleMap::TextualHeader;

View File

@ -0,0 +1,8 @@
#ifdef GIMME_AN_M
#ifndef M_H
#define M_H
const int m = 42;
#endif
#endif

View File

@ -0,0 +1 @@
#include "m.h"

View File

@ -61,5 +61,10 @@ module XL {
textual header "l.h" textual header "l.h"
} }
module XM {
private textual header "m.h"
textual header "m2.h"
}
module XS { module XS {
} }

View File

@ -1,6 +1,6 @@
// RUN: rm -rf %t // 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 -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 #define GIMME_A_K
#include "k.h" #include "k.h"
@ -8,4 +8,11 @@
#define GIMME_AN_L #define GIMME_AN_L
#include "l.h" // expected-error {{module XG does not depend on a module exporting 'l.h'}} #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; const int g = k + l;

View File

@ -6650,11 +6650,7 @@ CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo(); HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE); ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
if (Module *Mod = Header.getModule()) { return Header.getModule();
if (Header.getRole() != ModuleMap::ExcludedHeader)
return Mod;
}
return nullptr;
} }
CXFile clang_Module_getASTFile(CXModule CXMod) { CXFile clang_Module_getASTFile(CXModule CXMod) {