2014-10-25 5:23 GMT+09:00 Richard Smith <[email protected]>: > 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
