Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
18 changes: 16 additions & 2 deletions clang/include/clang/Basic/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,22 @@ class alignas(8) Module {
DirectoryEntryRef Entry;
};

/// The headers that are part of this module.
SmallVector<Header, 2> Headers[5];
private:
unsigned HeaderKindBeginIndex[6] = {};
SmallVector<Header, 2> HeadersStorage;

public:
ArrayRef<Header> getHeaders(HeaderKind HK) const {
auto BeginIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK];
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
return {BeginIt, EndIt};
}
void addHeader(HeaderKind HK, Header H) {
auto EndIt = HeadersStorage.begin() + HeaderKindBeginIndex[HK + 1];
HeadersStorage.insert(EndIt, std::move(H));
for (unsigned HKI = HK + 1; HKI != 6; ++HKI)
++HeaderKindBeginIndex[HKI];
}

/// Stored information about a header directive that was found in the
/// module map file but has not been resolved to a file.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {

for (auto &K : Kinds) {
assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
for (auto &H : Headers[K.Kind]) {
for (auto &H : getHeaders(K.Kind)) {
OS.indent(Indent + 2);
OS << K.Prefix << "header \"";
OS.write_escaped(H.NameAsWritten);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ static std::error_code collectModuleHeaderIncludes(

// Add includes for each of these headers.
for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
for (Module::Header &H : Module->Headers[HK]) {
for (const Module::Header &H : Module->getHeaders(HK)) {
Module->addTopHeader(H.Entry);
// Use the path as specified in the module map file. We'll look for this
// file relative to the module build directory (the directory containing
Expand Down
20 changes: 11 additions & 9 deletions clang/lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,12 @@ static bool violatesPrivateInclude(Module *RequestingModule,
// as obtained from the lookup and as obtained from the module.
// This check is not cheap, so enable it only for debugging.
bool IsPrivate = false;
SmallVectorImpl<Module::Header> *HeaderList[] = {
&Header.getModule()->Headers[Module::HK_Private],
&Header.getModule()->Headers[Module::HK_PrivateTextual]};
for (auto *Hs : HeaderList)
ArrayRef<Module::Header> HeaderList[] = {
Header.getModule()->getHeaders(Module::HK_Private),
Header.getModule()->getHeaders(Module::HK_PrivateTextual)};
for (auto Hs : HeaderList)
IsPrivate |= llvm::any_of(
*Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
Hs, [&](const Module::Header &H) { return H.Entry == IncFileEnt; });
assert(IsPrivate && "inconsistent headers and roles");
}
#endif
Expand Down Expand Up @@ -1296,27 +1296,29 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role, bool Imported) {
KnownHeader KH(Mod, Role);

FileEntryRef HeaderEntry = Header.Entry;

// Only add each header to the headers list once.
// FIXME: Should we diagnose if a header is listed twice in the
// same module definition?
auto &HeaderList = Headers[Header.Entry];
auto &HeaderList = Headers[HeaderEntry];
if (llvm::is_contained(HeaderList, KH))
return;

HeaderList.push_back(KH);
Mod->Headers[headerRoleToKind(Role)].push_back(Header);
Mod->addHeader(headerRoleToKind(Role), std::move(Header));

bool isCompilingModuleHeader = Mod->isForBuilding(LangOpts);
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
HeaderInfo.MarkFileModuleHeader(HeaderEntry, Role,
isCompilingModuleHeader);
}

// Notify callbacks that we just added a new header.
for (const auto &Cb : Callbacks)
Cb->moduleMapAddHeader(Header.Entry.getName());
Cb->moduleMapAddHeader(HeaderEntry.getName());
}

FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3070,9 +3070,9 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Module::HK_PrivateTextual},
{SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Module::HK_Excluded}
};
for (auto &HL : HeaderLists) {
for (const auto &HL : HeaderLists) {
RecordData::value_type Record[] = {HL.RecordKind};
for (auto &H : Mod->Headers[HL.HeaderKind])
for (const auto &H : Mod->getHeaders(HL.HeaderKind))
Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten);
}

Expand Down
Loading