From: Douglas Gregor Date: Fri, 27 Jan 2012 19:52:33 +0000 (+0000) Subject: Introduce module attributes into the module map grammar, along with a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6f;p=clang Introduce module attributes into the module map grammar, along with a single attribute ("system") that allows us to mark a module as being a "system" module. Each of the headers that makes up a system module is considered to be a system header, so that we (for example) suppress warnings there. If a module is being inferred for a framework, and that framework directory is within a system frameworks directory, infer it as a system framework. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149143 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 936a72e8e7..3a564c4aa8 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -391,6 +391,8 @@ def err_mmap_expected_module_name : Error<"expected module name">; def err_mmap_expected_lbrace : Error<"expected '{' to start module '%0'">; def err_mmap_expected_rbrace : Error<"expected '}'">; def note_mmap_lbrace_match : Note<"to match this '{'">; +def err_mmap_expected_rsquare : Error<"expected ']' to close attribute">; +def note_mmap_lsquare_match : Note<"to match this ']'">; def err_mmap_expected_member : Error< "expected umbrella, header, submodule, or module export">; def err_mmap_expected_header : Error<"expected a header name after '%0'">; @@ -429,6 +431,9 @@ def err_mmap_explicit_top_level : Error< def err_mmap_nested_submodule_id : Error< "qualified module name can only be used to define modules at the top level">; def err_mmap_expected_feature : Error<"expected a feature name">; +def err_mmap_expected_attribute : Error<"expected an attribute name">; +def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">, + InGroup; def warn_auto_module_import : Warning< "treating #%select{include|import|include_next|__include_macros}0 as an " diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h index 19292950f5..e75f43e0e9 100644 --- a/include/clang/Basic/Module.h +++ b/include/clang/Basic/Module.h @@ -86,6 +86,10 @@ public: /// \brief Whether this is an explicit submodule. unsigned IsExplicit : 1; + /// \brief Whether this is a "system" module (which assumes that all + /// headers in it are system headers). + unsigned IsSystem : 1; + /// \brief Whether we should infer submodules for this module based on /// the headers. /// @@ -154,10 +158,11 @@ public: bool IsFramework) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), Umbrella(), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), - IsExplicit(false), InferSubmodules(false), InferExplicitSubmodules(false), + IsExplicit(false), IsSystem(false), + InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), NameVisibility(Hidden) { } - /// \brief Construct a new module or submodule. + /// \brief Construct a new module or submodule. Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit); diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 038b8c65d0..848ae70308 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -618,9 +618,10 @@ public: FileID getMainFileID() const { return MainFileID; } /// createMainFileID - Create the FileID for the main source file. - FileID createMainFileID(const FileEntry *SourceFile) { + FileID createMainFileID(const FileEntry *SourceFile, + SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) { assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = createFileID(SourceFile, SourceLocation(), SrcMgr::C_User); + MainFileID = createFileID(SourceFile, SourceLocation(), Kind); return MainFileID; } diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index b488cde6e6..1e5994fc58 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ #include "clang/Frontend/CompilerInvocation.h" +#include "clang/Basic/SourceManager.h" #include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -627,17 +628,19 @@ public: /// as the main file. /// /// \return True on success. - bool InitializeSourceManager(StringRef InputFile); + bool InitializeSourceManager(StringRef InputFile, + SrcMgr::CharacteristicKind Kind = SrcMgr::C_User); /// InitializeSourceManager - Initialize the source manager to set InputFile /// as the main file. /// /// \return True on success. static bool InitializeSourceManager(StringRef InputFile, - DiagnosticsEngine &Diags, - FileManager &FileMgr, - SourceManager &SourceMgr, - const FrontendOptions &Opts); + SrcMgr::CharacteristicKind Kind, + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr, + const FrontendOptions &Opts); /// } diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 08c683e2da..f18fdebba7 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -76,9 +76,12 @@ struct FrontendInputFile { /// \brief The kind of input, e.g., C source, AST file, LLVM IR. InputKind Kind; + /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input). + bool IsSystem; + FrontendInputFile() : Kind(IK_None) { } - FrontendInputFile(StringRef File, InputKind Kind) - : File(File.str()), Kind(Kind) { } + FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) + : File(File.str()), Kind(Kind), IsSystem(IsSystem) { } }; /// FrontendOptions - Options for controlling the behavior of the frontend. diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 10242fa264..f61f2adc5b 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -401,9 +401,13 @@ public: /// /// \param Dir The framework directory (e.g., ModuleName.framework). /// + /// \param IsSystem Whether the framework directory is part of the system + /// frameworks. + /// /// \returns The module, if found; otherwise, null. Module *getFrameworkModule(StringRef Name, - const DirectoryEntry *Dir); + const DirectoryEntry *Dir, + bool IsSystem); /// \brief Retrieve the module map. ModuleMap &getModuleMap() { return ModMap; } diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index b017a05e97..64358c83e5 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -159,7 +159,7 @@ public: /// framework directory. Module *inferFrameworkModule(StringRef ModuleName, const DirectoryEntry *FrameworkDir, - Module *Parent); + bool IsSystem, Module *Parent); /// \brief Retrieve the module map file containing the definition of the given /// module. diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index ff09441802..015f421f9d 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -24,9 +24,9 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Umbrella(), IsAvailable(true), IsFromModuleFile(false), - IsFramework(IsFramework), IsExplicit(IsExplicit), InferSubmodules(false), - InferExplicitSubmodules(false), InferExportWildcard(false), - NameVisibility(Hidden) + IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), + InferSubmodules(false), InferExplicitSubmodules(false), + InferExportWildcard(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) @@ -172,8 +172,15 @@ void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { OS << "framework "; if (IsExplicit) OS << "explicit "; - OS << "module " << Name << " {\n"; + OS << "module " << Name; + if (IsSystem) { + OS.indent(Indent + 2); + OS << " [system]"; + } + + OS << " {\n"; + if (!Requires.empty()) { OS.indent(Indent + 2); OS << "requires "; diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index c3f3e3711a..b8075ed87a 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -577,12 +577,15 @@ CompilerInstance::createOutputFile(StringRef OutputPath, // Initialization Utilities -bool CompilerInstance::InitializeSourceManager(StringRef InputFile) { - return InitializeSourceManager(InputFile, getDiagnostics(), getFileManager(), - getSourceManager(), getFrontendOpts()); +bool CompilerInstance::InitializeSourceManager(StringRef InputFile, + SrcMgr::CharacteristicKind Kind){ + return InitializeSourceManager(InputFile, Kind, getDiagnostics(), + getFileManager(), getSourceManager(), + getFrontendOpts()); } bool CompilerInstance::InitializeSourceManager(StringRef InputFile, + SrcMgr::CharacteristicKind Kind, DiagnosticsEngine &Diags, FileManager &FileMgr, SourceManager &SourceMgr, @@ -594,7 +597,7 @@ bool CompilerInstance::InitializeSourceManager(StringRef InputFile, Diags.Report(diag::err_fe_error_reading) << InputFile; return false; } - SourceMgr.createMainFileID(File); + SourceMgr.createMainFileID(File, Kind); } else { llvm::OwningPtr SB; if (llvm::MemoryBuffer::getSTDIN(SB)) { @@ -604,7 +607,7 @@ bool CompilerInstance::InitializeSourceManager(StringRef InputFile, } const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), SB->getBufferSize(), 0); - SourceMgr.createMainFileID(File); + SourceMgr.createMainFileID(File, Kind); SourceMgr.overrideFileContents(File, SB.take()); } diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp index 5a15847aea..11ac572479 100644 --- a/lib/Frontend/FrontendAction.cpp +++ b/lib/Frontend/FrontendAction.cpp @@ -320,7 +320,10 @@ void FrontendAction::Execute() { // Initialize the main file entry. This needs to be delayed until after PCH // has loaded. if (!isCurrentFileAST()) { - if (!CI.InitializeSourceManager(getCurrentFile())) + if (!CI.InitializeSourceManager(getCurrentFile(), + getCurrentInput().IsSystem + ? SrcMgr::C_System + : SrcMgr::C_User)) return; } diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 272474cea7..e99e47eb19 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -256,7 +256,8 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, // Simple case: we have an umbrella header and there are no additional // includes, we can just parse the umbrella header directly. setCurrentInput(FrontendInputFile(UmbrellaHeader->getName(), - getCurrentFileKind())); + getCurrentFileKind(), + Module->IsSystem)); return true; } @@ -313,7 +314,8 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, llvm::MemoryBuffer *HeaderContentsBuf = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents); CI.getSourceManager().overrideFileContents(HeaderFile, HeaderContentsBuf); - setCurrentInput(FrontendInputFile(HeaderName, getCurrentFileKind())); + setCurrentInput(FrontendInputFile(HeaderName, getCurrentFileKind(), + Module->IsSystem)); return true; } diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 7af7c93b7b..ff63bdb31b 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -134,7 +134,9 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); if (const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(FrameworkDirName)) { - Module = getFrameworkModule(ModuleName, FrameworkDir); + bool IsSystem + = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; + Module = getFrameworkModule(ModuleName, FrameworkDir, IsSystem); if (Module) break; } @@ -319,8 +321,10 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( Module *Module = 0; if (SuggestedModule) { if (const DirectoryEntry *FrameworkDir - = FileMgr.getDirectory(FrameworkName)) - Module = HS.getFrameworkModule(ModuleName, FrameworkDir); + = FileMgr.getDirectory(FrameworkName)) { + bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; + Module = HS.getFrameworkModule(ModuleName, FrameworkDir, IsSystem); + } } // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" @@ -858,7 +862,8 @@ Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { } Module *HeaderSearch::getFrameworkModule(StringRef Name, - const DirectoryEntry *Dir) { + const DirectoryEntry *Dir, + bool IsSystem) { if (Module *Module = ModMap.findModule(Name)) return Module; @@ -907,7 +912,8 @@ Module *HeaderSearch::getFrameworkModule(StringRef Name, // Try to infer a module map from the top-level framework directory. Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), - TopFrameworkDir, + TopFrameworkDir, + IsSystem, /*Parent=*/0); // Follow the submodule path to find the requested (sub)framework module diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index 08a1e23d10..708da94585 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -284,6 +284,7 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, Module * ModuleMap::inferFrameworkModule(StringRef ModuleName, const DirectoryEntry *FrameworkDir, + bool IsSystem, Module *Parent) { // Check whether we've already found this module. if (Module *Mod = lookupModuleQualified(ModuleName, Parent)) @@ -305,6 +306,9 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, Module *Result = new Module(ModuleName, SourceLocation(), Parent, /*IsFramework=*/true, /*IsExplicit=*/false); + if (IsSystem) + Result->IsSystem = IsSystem; + if (!Parent) Modules[ModuleName] = Result; @@ -338,7 +342,7 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, = FileMgr.getDirectory(Dir->path())) { // FIXME: Do we want to warn about subframeworks without umbrella headers? inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir, - Result); + IsSystem, Result); } } @@ -454,7 +458,9 @@ namespace clang { Star, StringLiteral, LBrace, - RBrace + RBrace, + LSquare, + RSquare } Kind; unsigned Location; @@ -579,6 +585,10 @@ retry: Tok.Kind = MMToken::LBrace; break; + case tok::l_square: + Tok.Kind = MMToken::LSquare; + break; + case tok::period: Tok.Kind = MMToken::Period; break; @@ -587,6 +597,10 @@ retry: Tok.Kind = MMToken::RBrace; break; + case tok::r_square: + Tok.Kind = MMToken::RSquare; + break; + case tok::star: Tok.Kind = MMToken::Star; break; @@ -625,27 +639,42 @@ retry: void ModuleMapParser::skipUntil(MMToken::TokenKind K) { unsigned braceDepth = 0; + unsigned squareDepth = 0; do { switch (Tok.Kind) { case MMToken::EndOfFile: return; case MMToken::LBrace: - if (Tok.is(K) && braceDepth == 0) + if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) return; ++braceDepth; break; - + + case MMToken::LSquare: + if (Tok.is(K) && braceDepth == 0 && squareDepth == 0) + return; + + ++squareDepth; + break; + case MMToken::RBrace: if (braceDepth > 0) --braceDepth; else if (Tok.is(K)) return; break; - + + case MMToken::RSquare: + if (squareDepth > 0) + --squareDepth; + else if (Tok.is(K)) + return; + break; + default: - if (braceDepth == 0 && Tok.is(K)) + if (braceDepth == 0 && squareDepth == 0 && Tok.is(K)) return; break; } @@ -681,10 +710,28 @@ bool ModuleMapParser::parseModuleId(ModuleId &Id) { return false; } +namespace { + /// \brief Enumerates the known attributes. + enum AttributeKind { + /// \brief An unknown attribute. + AT_unknown, + /// \brief The 'system' attribute. + AT_system + }; +} + /// \brief Parse a module declaration. /// /// module-declaration: -/// 'explicit'[opt] 'framework'[opt] 'module' module-id { module-member* } +/// 'explicit'[opt] 'framework'[opt] 'module' module-id attributes[opt] +/// { module-member* } +/// +/// attributes: +/// attribute attributes +/// attribute +/// +/// attribute: +/// [ identifier ] /// /// module-member: /// requires-declaration @@ -777,6 +824,49 @@ void ModuleMapParser::parseModuleDecl() { StringRef ModuleName = Id.back().first; SourceLocation ModuleNameLoc = Id.back().second; + // Parse the optional attribute list. + bool IsSystem = false; + while (Tok.is(MMToken::LSquare)) { + // Consume the '['. + SourceLocation LSquareLoc = consumeToken(); + + // Check whether we have an attribute name here. + if (!Tok.is(MMToken::Identifier)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_attribute); + skipUntil(MMToken::RSquare); + if (Tok.is(MMToken::RSquare)) + consumeToken(); + continue; + } + + // Decode the attribute name. + AttributeKind Attribute + = llvm::StringSwitch(Tok.getString()) + .Case("system", AT_system) + .Default(AT_unknown); + switch (Attribute) { + case AT_unknown: + Diags.Report(Tok.getLocation(), diag::warn_mmap_unknown_attribute) + << Tok.getString(); + break; + + case AT_system: + IsSystem = true; + break; + } + consumeToken(); + + // Consume the ']'. + if (!Tok.is(MMToken::RSquare)) { + Diags.Report(Tok.getLocation(), diag::err_mmap_expected_rsquare); + Diags.Report(LSquareLoc, diag::note_mmap_lsquare_match); + skipUntil(MMToken::RSquare); + } + + if (Tok.is(MMToken::RSquare)) + consumeToken(); + } + // Parse the opening brace. if (!Tok.is(MMToken::LBrace)) { Diags.Report(Tok.getLocation(), diag::err_mmap_expected_lbrace) @@ -818,6 +908,8 @@ void ModuleMapParser::parseModuleDecl() { ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit).first; ActiveModule->DefinitionLoc = ModuleNameLoc; + if (IsSystem) + ActiveModule->IsSystem = true; bool Done = false; do { @@ -1251,8 +1343,10 @@ bool ModuleMapParser::parseModuleMapFile() { case MMToken::HeaderKeyword: case MMToken::Identifier: case MMToken::LBrace: + case MMToken::LSquare: case MMToken::Period: case MMToken::RBrace: + case MMToken::RSquare: case MMToken::RequiresKeyword: case MMToken::Star: case MMToken::StringLiteral: diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 42a848df78..71734027bf 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3130,9 +3130,10 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { SubmoduleID Parent = getGlobalSubmoduleID(F, Record[1]); bool IsFramework = Record[2]; bool IsExplicit = Record[3]; - bool InferSubmodules = Record[4]; - bool InferExplicitSubmodules = Record[5]; - bool InferExportWildcard = Record[6]; + bool IsSystem = Record[4]; + bool InferSubmodules = Record[5]; + bool InferExplicitSubmodules = Record[6]; + bool InferExportWildcard = Record[7]; Module *ParentModule = 0; if (Parent) @@ -3151,6 +3152,7 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { } CurrentModule->IsFromModuleFile = true; + CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem; CurrentModule->InferSubmodules = InferSubmodules; CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules; CurrentModule->InferExportWildcard = InferExportWildcard; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 838ec35173..b715d6ce3f 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1897,8 +1897,9 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules... Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit... - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild... Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev); @@ -1949,6 +1950,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { } Record.push_back(Mod->IsFramework); Record.push_back(Mod->IsExplicit); + Record.push_back(Mod->IsSystem); Record.push_back(Mod->InferSubmodules); Record.push_back(Mod->InferExplicitSubmodules); Record.push_back(Mod->InferExportWildcard); diff --git a/test/Modules/Inputs/NoUmbrella.framework/Headers/A.h b/test/Modules/Inputs/NoUmbrella.framework/Headers/A.h index 0de118c4f8..73f32bff40 100644 --- a/test/Modules/Inputs/NoUmbrella.framework/Headers/A.h +++ b/test/Modules/Inputs/NoUmbrella.framework/Headers/A.h @@ -1 +1,8 @@ int no_umbrella_A; + +inline int has_warning(int x) { + if (x > 0) + return x; + // Note: warning here is suppressed because this module is considered a + // "system" module. +} diff --git a/test/Modules/Inputs/NoUmbrella.framework/module.map b/test/Modules/Inputs/NoUmbrella.framework/module.map index 986cca995c..4a4d9702c5 100644 --- a/test/Modules/Inputs/NoUmbrella.framework/module.map +++ b/test/Modules/Inputs/NoUmbrella.framework/module.map @@ -1,4 +1,4 @@ -framework module NoUmbrella { +framework module NoUmbrella [system] { umbrella "Headers" module * { }