r220589 - [modules] Support combining 'textual' with 'private'.
NAKAMURA Takumi
geek4civic at gmail.com
Sat Oct 25 17:30:29 PDT 2014
2014-10-25 5:23 GMT+09:00 Richard Smith <richard-llvm at metafoo.co.uk>:
> Author: rsmith
> Date: Fri Oct 24 15:23:01 2014
> New Revision: 220589
>
> URL: http://llvm.org/viewvc/llvm-project?rev=220589&view=rev
> Log:
> [modules] Support combining 'textual' with 'private'.
>
> Added:
> cfe/trunk/test/Modules/Inputs/declare-use/m.h
> - copied unchanged from r220460, cfe/trunk/test/Modules/Inputs/declare-use/m.h
> cfe/trunk/test/Modules/Inputs/declare-use/m2.h
> - copied unchanged from r220460, cfe/trunk/test/Modules/Inputs/declare-use/m2.h
> Modified:
> cfe/trunk/docs/Modules.rst
> cfe/trunk/include/clang/Basic/Module.h
> cfe/trunk/include/clang/Lex/ModuleMap.h
> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> cfe/trunk/lib/Lex/ModuleMap.cpp
> cfe/trunk/lib/Serialization/ASTReader.cpp
> cfe/trunk/lib/Serialization/ASTWriter.cpp
> cfe/trunk/test/Modules/Inputs/declare-use/module.map
> cfe/trunk/test/Modules/textual-headers.cpp
>
> Modified: cfe/trunk/docs/Modules.rst
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/Modules.rst?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/docs/Modules.rst (original)
> +++ cfe/trunk/docs/Modules.rst Fri Oct 24 15:23:01 2014
> @@ -445,9 +445,8 @@ A header declaration specifies that a pa
> .. parsed-literal::
>
> *header-declaration*:
> - ``umbrella``:sub:`opt` ``header`` *string-literal*
> - ``private`` ``header`` *string-literal*
> - ``textual`` ``header`` *string-literal*
> + ``private``:sub:`opt` ``textual``:sub:`opt` ``header`` *string-literal*
> + ``umbrella`` ``header`` *string-literal*
> ``exclude`` ``header`` *string-literal*
>
> A header declaration that does not contain ``exclude`` nor ``textual`` specifies a header that contributes to the enclosing module. Specifically, when the module is built, the named header will be parsed and its declarations will be (logically) placed into the enclosing submodule.
> @@ -464,14 +463,14 @@ A header with the ``private`` specifier
>
> A header with the ``textual`` specifier will not be included when the module is built, and will be textually included if it is named by a ``#include`` directive. However, it is considered to be part of the module for the purpose of checking *use-declaration*\s.
>
> -A header with the ``exclude`` specifier is excluded from the module. It will not be included when the module is built, nor will it be considered to be part of the module.
> +A header with the ``exclude`` specifier is excluded from the module. It will not be included when the module is built, nor will it be considered to be part of the module, even if an ``umbrella`` header or directory would otherwise make it part of the module.
>
> -**Example**: The C header ``assert.h`` is an excellent candidate for an excluded header, because it is meant to be included multiple times (possibly with different ``NDEBUG`` settings).
> +**Example**: The C header ``assert.h`` is an excellent candidate for a textual header, because it is meant to be included multiple times (possibly with different ``NDEBUG`` settings). However, declarations within it should typically be split into a separate modular header.
>
> .. parsed-literal::
>
> module std [system] {
> - exclude header "assert.h"
> + textual header "assert.h"
> }
>
> A given header shall not be referenced by more than one *header-declaration*.
>
> Modified: cfe/trunk/include/clang/Basic/Module.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Module.h (original)
> +++ cfe/trunk/include/clang/Basic/Module.h Fri Oct 24 15:23:01 2014
> @@ -84,9 +84,6 @@ public:
> /// \brief The headers that are part of this module.
> SmallVector<const FileEntry *, 2> NormalHeaders;
>
> - /// \brief The headers that are explicitly excluded from this module.
> - SmallVector<const FileEntry *, 2> ExcludedHeaders;
> -
> /// \brief The headers that are logically part of this module but
> /// must be textually included.
> SmallVector<const FileEntry *, 2> TextualHeaders;
> @@ -94,6 +91,13 @@ public:
> /// \brief The headers that are private to this module.
> SmallVector<const FileEntry *, 2> PrivateHeaders;
>
> + /// \brief The headers that are private to this module and are to be
> + /// included textually.
> + SmallVector<const FileEntry *, 2> PrivateTextualHeaders;
> +
> + /// \brief The headers that are explicitly excluded from this module.
> + SmallVector<const FileEntry *, 2> ExcludedHeaders;
> +
> /// \brief Information about a header directive as found in the module map
> /// file.
> struct HeaderDirective {
>
> Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
> +++ cfe/trunk/include/clang/Lex/ModuleMap.h Fri Oct 24 15:23:01 2014
> @@ -65,20 +65,21 @@ private:
> llvm::StringMap<Module *> Modules;
>
> public:
> - /// \brief Describes the role of a module header.
> + /// \brief Flags describing the role of a module header.
> enum ModuleHeaderRole {
> /// \brief This header is normally included in the module.
> - NormalHeader,
> + NormalHeader = 0x0,
> /// \brief This header is included but private.
> - PrivateHeader,
> + PrivateHeader = 0x1,
> /// \brief This header is part of the module (for layering purposes) but
> /// should be textually included.
> - TextualHeader,
> + TextualHeader = 0x2,
> // Caution: Adding an enumerator needs other changes.
> // Adjust the number of bits for KnownHeader::Storage.
> // Adjust the bitfield HeaderFileInfo::HeaderRole size.
> // Adjust the HeaderFileInfoTrait::ReadData streaming.
> // Adjust the HeaderFileInfoTrait::EmitData streaming.
> + // Adjust ModuleMap::addHeader.
> };
>
> /// \brief A header that is known to reside within a given module,
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Oct 24 15:23:01 2014
> @@ -645,6 +645,9 @@ namespace clang {
> /// \brief Specifies a header that is part of the module but must be
> /// textually included.
> SUBMODULE_TEXTUAL_HEADER = 14,
> + /// \brief Specifies a header that is private to this submodule but
> + /// must be textually included.
> + SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15,
> };
>
> /// \brief Record types used within a comments block.
>
> Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
> +++ cfe/trunk/lib/Lex/ModuleMap.cpp Fri Oct 24 15:23:01 2014
> @@ -202,7 +202,7 @@ ModuleMap::findHeaderInUmbrellaDirs(cons
> return KnownHeader();
> }
>
> -// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
> +// Returns true if RequestingModule directly uses RequestedModule.
> static bool directlyUses(const Module *RequestingModule,
> const Module *RequestedModule) {
> return std::find(RequestingModule->DirectUses.begin(),
> @@ -214,19 +214,19 @@ static bool violatesPrivateInclude(Modul
> const FileEntry *IncFileEnt,
> ModuleMap::ModuleHeaderRole Role,
> Module *RequestedModule) {
> - #ifndef NDEBUG
> + bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
> +#ifndef NDEBUG
> // Check for consistency between the module header role
> // as obtained from the lookup and as obtained from the module.
> // This check is not cheap, so enable it only for debugging.
> - SmallVectorImpl<const FileEntry *> &PvtHdrs
> - = RequestedModule->PrivateHeaders;
> - SmallVectorImpl<const FileEntry *>::iterator Look
> - = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
> - bool IsPrivate = Look != PvtHdrs.end();
> - assert((IsPrivate && Role == ModuleMap::PrivateHeader)
> - || (!IsPrivate && Role != ModuleMap::PrivateHeader));
> - #endif
> - return Role == ModuleMap::PrivateHeader &&
> + bool IsPrivate = false;
> + for (auto *Hdrs : {&RequestedModule->PrivateHeaders,
> + &RequestedModule->PrivateTextualHeaders})
> + IsPrivate |=
> + std::find(Hdrs->begin(), Hdrs->end(), IncFileEnt) != Hdrs->end();
> + assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
> +#endif
> + return IsPrivateRole &&
> RequestedModule->getTopLevelModule() != RequestingModule;
> }
>
> @@ -316,13 +316,13 @@ ModuleMap::findModuleForHeader(const Fil
> HeadersMap::iterator Known = findKnownHeader(File);
>
> auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
> - if (!IncludeTextualHeaders && R.getRole() == ModuleMap::TextualHeader)
> + if (!IncludeTextualHeaders && (R.getRole() & ModuleMap::TextualHeader))
> return ModuleMap::KnownHeader();
> return R;
> };
>
> if (Known != Headers.end()) {
> - ModuleMap::KnownHeader Result = KnownHeader();
> + ModuleMap::KnownHeader Result;
>
> // Iterate over all modules that 'File' is part of to find the best fit.
> for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
> @@ -343,14 +343,9 @@ ModuleMap::findModuleForHeader(const Fil
> !directlyUses(RequestingModule, I->getModule()))
> continue;
>
> - Result = *I;
> - // If 'File' is a public header of this module, this is as good as we
> - // are going to get.
> - // FIXME: If we have a RequestingModule, we should prefer the header from
> - // that module.
> - if (I->getRole() == ModuleMap::NormalHeader ||
> - I->getRole() == ModuleMap::TextualHeader)
> - break;
> + // Prefer a public header over a private header.
> + if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
> + Result = *I;
> }
> return MakeResult(Result);
> }
> @@ -783,13 +778,12 @@ void ModuleMap::setUmbrellaDir(Module *M
>
> void ModuleMap::addHeader(Module *Mod, const FileEntry *Header,
> ModuleHeaderRole Role) {
> - if (Role == TextualHeader) {
> - Mod->TextualHeaders.push_back(Header);
> - } else {
> - if (Role == PrivateHeader)
> - Mod->PrivateHeaders.push_back(Header);
> - else
> - Mod->NormalHeaders.push_back(Header);
> + auto HeaderLists = {&Mod->NormalHeaders, &Mod->PrivateHeaders,
> + &Mod->TextualHeaders, &Mod->PrivateTextualHeaders};
> + assert(Role >= 0 && Role < HeaderLists.size() && "unknown header role");
> + HeaderLists.begin()[Role]->push_back(Header);
> +
> + if (!(Role & TextualHeader)) {
> bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
> HeaderInfo.MarkFileModuleHeader(Header, Role, isCompilingModuleHeader);
> }
MSC17 (aka VS2012) doesn't like it.
http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11174
May I rewrite it into like?
switch ((int)Role) {
default: llvm_unreachable("unknown header role");
case NormalHeader: Mod->NormalHeaders.push_back(Header); break;
case PrivateHeader: Mod->PrivateHeaders.push_back(Header); break;
case TextualHeader: Mod->TextualHeaders.push_back(Header); break;
case PrivateHeader | TextualHeader:
Mod->PrivateTextualHeaders.push_back(Header); break;
}
> @@ -1475,16 +1469,9 @@ void ModuleMapParser::parseModuleDecl()
> parseRequiresDecl();
> break;
>
> - case MMToken::TextualKeyword: {
> - SourceLocation TextualLoc = consumeToken();
> - if (Tok.is(MMToken::HeaderKeyword)) {
> - parseHeaderDecl(MMToken::TextualKeyword, TextualLoc);
> - } else {
> - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
> - << "textual";
> - }
> + case MMToken::TextualKeyword:
> + parseHeaderDecl(MMToken::TextualKeyword, consumeToken());
> break;
> - }
>
> case MMToken::UmbrellaKeyword: {
> SourceLocation UmbrellaLoc = consumeToken();
> @@ -1494,31 +1481,17 @@ void ModuleMapParser::parseModuleDecl()
> parseUmbrellaDirDecl(UmbrellaLoc);
> break;
> }
> -
> - case MMToken::ExcludeKeyword: {
> - SourceLocation ExcludeLoc = consumeToken();
> - if (Tok.is(MMToken::HeaderKeyword)) {
> - parseHeaderDecl(MMToken::ExcludeKeyword, ExcludeLoc);
> - } else {
> - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
> - << "exclude";
> - }
> +
> + case MMToken::ExcludeKeyword:
> + parseHeaderDecl(MMToken::ExcludeKeyword, consumeToken());
> break;
> - }
> -
> - case MMToken::PrivateKeyword: {
> - SourceLocation PrivateLoc = consumeToken();
> - if (Tok.is(MMToken::HeaderKeyword)) {
> - parseHeaderDecl(MMToken::PrivateKeyword, PrivateLoc);
> - } else {
> - Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
> - << "private";
> - }
> +
> + case MMToken::PrivateKeyword:
> + parseHeaderDecl(MMToken::PrivateKeyword, consumeToken());
> break;
> - }
> -
> +
> case MMToken::HeaderKeyword:
> - parseHeaderDecl(MMToken::HeaderKeyword, SourceLocation());
> + parseHeaderDecl(MMToken::HeaderKeyword, consumeToken());
> break;
>
> case MMToken::LinkKeyword:
> @@ -1673,16 +1646,37 @@ static void appendSubframeworkPaths(Modu
> /// \brief Parse a header declaration.
> ///
> /// header-declaration:
> -/// 'exclude'[opt] 'header' string-literal
> -/// 'private'[opt] 'header' string-literal
> /// 'textual'[opt] 'header' string-literal
> -/// 'umbrella'[opt] 'header' string-literal
> +/// 'private' 'textual'[opt] 'header' string-literal
> +/// 'exclude' 'header' string-literal
> +/// 'umbrella' 'header' string-literal
> ///
> /// FIXME: Support 'private textual header'.
> void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
> SourceLocation LeadingLoc) {
> - assert(Tok.is(MMToken::HeaderKeyword));
> - consumeToken();
> + // We've already consumed the first token.
> + ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
> + if (LeadingToken == MMToken::PrivateKeyword) {
> + Role = ModuleMap::PrivateHeader;
> + // 'private' may optionally be followed by 'textual'.
> + if (Tok.is(MMToken::TextualKeyword)) {
> + LeadingToken = Tok.Kind;
> + consumeToken();
> + }
> + }
> + if (LeadingToken == MMToken::TextualKeyword)
> + Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
> +
> + if (LeadingToken != MMToken::HeaderKeyword) {
> + if (!Tok.is(MMToken::HeaderKeyword)) {
> + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_header)
> + << (LeadingToken == MMToken::PrivateKeyword ? "private" :
> + LeadingToken == MMToken::ExcludeKeyword ? "exclude" :
> + LeadingToken == MMToken::TextualKeyword ? "textual" : "umbrella");
> + return;
> + }
> + consumeToken();
> + }
>
> // Parse the header name.
> if (!Tok.is(MMToken::StringLiteral)) {
> @@ -1770,21 +1764,13 @@ void ModuleMapParser::parseHeaderDecl(MM
> } else if (LeadingToken == MMToken::ExcludeKeyword) {
> Map.excludeHeader(ActiveModule, File);
> } else {
> - // Record this header.
> - ModuleMap::ModuleHeaderRole Role = ModuleMap::NormalHeader;
> - if (LeadingToken == MMToken::PrivateKeyword)
> - Role = ModuleMap::PrivateHeader;
> - else if (LeadingToken == MMToken::TextualKeyword)
> - Role = ModuleMap::TextualHeader;
> - else
> - assert(LeadingToken == MMToken::HeaderKeyword);
> -
> // If there is a builtin counterpart to this file, add it now, before
> // the "real" header, so we build the built-in one first when building
> // the module.
> if (BuiltinFile)
> Map.addHeader(ActiveModule, BuiltinFile, Role);
>
> + // Record this header.
> Map.addHeader(ActiveModule, File, Role);
> }
> } else if (LeadingToken != MMToken::ExcludeKeyword) {
>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Oct 24 15:23:01 2014
> @@ -4461,26 +4461,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
> break;
> }
>
> - case SUBMODULE_HEADER: {
> - // We lazily associate headers with their modules via the HeaderInfoTable.
> + case SUBMODULE_HEADER:
> + case SUBMODULE_EXCLUDED_HEADER:
> + case SUBMODULE_PRIVATE_HEADER:
> + // We lazily associate headers with their modules via the HeaderInfo table.
> // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead
> // of complete filenames or remove it entirely.
> - break;
> - }
> -
> - case SUBMODULE_EXCLUDED_HEADER: {
> - // We lazily associate headers with their modules via the HeaderInfoTable.
> - // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead
> - // of complete filenames or remove it entirely.
> - break;
> - }
> + break;
>
> - case SUBMODULE_PRIVATE_HEADER: {
> - // We lazily associate headers with their modules via the HeaderInfoTable.
> - // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead
> - // of complete filenames or remove it entirely.
> - break;
> - }
> + case SUBMODULE_TEXTUAL_HEADER:
> + case SUBMODULE_PRIVATE_TEXTUAL_HEADER:
> + // FIXME: Textual headers are not marked in the HeaderInfo table. Load
> + // them here.
> + break;
>
> case SUBMODULE_TOPHEADER: {
> CurrentModule->addTopHeaderFilename(Blob);
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Oct 24 15:23:01 2014
> @@ -2370,7 +2370,7 @@ void ASTWriter::WriteSubmodules(Module *
> }
>
> // Enter the submodule description block.
> - Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/4);
> + Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5);
>
> // Write the abbreviations needed for the submodules block.
> using namespace llvm;
> @@ -2431,6 +2431,11 @@ void ASTWriter::WriteSubmodules(Module *
> unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
>
> Abbrev = new BitCodeAbbrev();
> + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER));
> + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
> + unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbrev);
> +
> + Abbrev = new BitCodeAbbrev();
> Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
> Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
> @@ -2504,40 +2509,25 @@ void ASTWriter::WriteSubmodules(Module *
> }
>
> // Emit the headers.
> - for (unsigned I = 0, N = Mod->NormalHeaders.size(); I != N; ++I) {
> - Record.clear();
> - Record.push_back(SUBMODULE_HEADER);
> - Stream.EmitRecordWithBlob(HeaderAbbrev, Record,
> - Mod->NormalHeaders[I]->getName());
> - }
> - // Emit the excluded headers.
> - for (unsigned I = 0, N = Mod->ExcludedHeaders.size(); I != N; ++I) {
> - Record.clear();
> - Record.push_back(SUBMODULE_EXCLUDED_HEADER);
> - Stream.EmitRecordWithBlob(ExcludedHeaderAbbrev, Record,
> - Mod->ExcludedHeaders[I]->getName());
> - }
> - // Emit the textual headers.
> - for (unsigned I = 0, N = Mod->TextualHeaders.size(); I != N; ++I) {
> - Record.clear();
> - Record.push_back(SUBMODULE_TEXTUAL_HEADER);
> - Stream.EmitRecordWithBlob(TextualHeaderAbbrev, Record,
> - Mod->TextualHeaders[I]->getName());
> - }
> - // Emit the private headers.
> - for (unsigned I = 0, N = Mod->PrivateHeaders.size(); I != N; ++I) {
> - Record.clear();
> - Record.push_back(SUBMODULE_PRIVATE_HEADER);
> - Stream.EmitRecordWithBlob(PrivateHeaderAbbrev, Record,
> - Mod->PrivateHeaders[I]->getName());
> - }
> - ArrayRef<const FileEntry *>
> - TopHeaders = Mod->getTopHeaders(PP->getFileManager());
> - for (unsigned I = 0, N = TopHeaders.size(); I != N; ++I) {
> - Record.clear();
> - Record.push_back(SUBMODULE_TOPHEADER);
> - Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record,
> - TopHeaders[I]->getName());
> + struct {
> + unsigned Kind;
> + unsigned Abbrev;
> + ArrayRef<const FileEntry*> Headers;
> + } HeaderLists[] = {
> + {SUBMODULE_HEADER, HeaderAbbrev, Mod->NormalHeaders},
> + {SUBMODULE_TEXTUAL_HEADER, TextualHeaderAbbrev, Mod->TextualHeaders},
> + {SUBMODULE_PRIVATE_HEADER, PrivateHeaderAbbrev, Mod->PrivateHeaders},
> + {SUBMODULE_PRIVATE_TEXTUAL_HEADER, PrivateTextualHeaderAbbrev,
> + Mod->PrivateTextualHeaders},
> + {SUBMODULE_EXCLUDED_HEADER, ExcludedHeaderAbbrev, Mod->ExcludedHeaders},
> + {SUBMODULE_TOPHEADER, TopHeaderAbbrev,
> + Mod->getTopHeaders(PP->getFileManager())}
> + };
> + for (auto &HL : HeaderLists) {
> + Record.clear();
> + Record.push_back(HL.Kind);
> + for (auto *H : HL.Headers)
> + Stream.EmitRecordWithBlob(HL.Abbrev, Record, H->getName());
> }
>
> // Emit the imports.
>
> Modified: cfe/trunk/test/Modules/Inputs/declare-use/module.map
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/declare-use/module.map?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/declare-use/module.map (original)
> +++ cfe/trunk/test/Modules/Inputs/declare-use/module.map Fri Oct 24 15:23:01 2014
> @@ -61,5 +61,10 @@ module XL {
> textual header "l.h"
> }
>
> +module XM {
> + private textual header "m.h"
> + textual header "m2.h"
> +}
> +
> module XS {
> }
>
> Modified: cfe/trunk/test/Modules/textual-headers.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/textual-headers.cpp?rev=220589&r1=220588&r2=220589&view=diff
> ==============================================================================
> --- cfe/trunk/test/Modules/textual-headers.cpp (original)
> +++ cfe/trunk/test/Modules/textual-headers.cpp Fri Oct 24 15:23:01 2014
> @@ -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 -fno-modules-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; // expected-error {{undeclared identifier}}
> +
> +#define GIMME_AN_M
> +#include "m.h" // expected-error {{use of private header from outside its module: 'm.h'}}
> +const int use_m_2 = m;
> +
> const int g = k + l;
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list