diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 8a5a798560de..5c748a538f6f 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -53,6 +53,9 @@ struct HeaderFileInfo { /// \brief Whether this header is part of a module. unsigned isModuleHeader : 1; + + /// \brief Whether this header is part of the module that we are building. + unsigned isCompilingModuleHeader : 1; /// \brief Whether this structure is considered to already have been /// "resolved", meaning that it was loaded from the external source. @@ -93,8 +96,8 @@ struct HeaderFileInfo { HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), isModuleHeader(false), Resolved(false), - IndexHeaderMapHeader(false), + External(false), isModuleHeader(false), isCompilingModuleHeader(false), + Resolved(false), IndexHeaderMapHeader(false), NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {} /// \brief Retrieve the controlling macro for this header file, if @@ -405,7 +408,7 @@ public: } /// \brief Mark the specified file as part of a module. - void MarkFileModuleHeader(const FileEntry *File); + void MarkFileModuleHeader(const FileEntry *File, bool IsCompiledModuleHeader); /// \brief Increment the count for the number of times the specified /// FileEntry has been entered. diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index dc75f1803cb7..9fe97d01110b 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -52,6 +52,9 @@ class ModuleMap { /// These are always simple C language options. LangOptions MMapLangOpts; + // The module that we are building; related to \c LangOptions::CurrentModule. + Module *CompilingModule; + /// \brief The top-level modules that are known. llvm::StringMap Modules; diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index 304bd6969a68..5e56e3d11309 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -866,12 +866,14 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { HFI.ControllingMacro || HFI.ControllingMacroID; } -void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE) { +void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, + bool isCompilingModuleHeader) { if (FE->getUID() >= FileInfo.size()) FileInfo.resize(FE->getUID()+1); HeaderFileInfo &HFI = FileInfo[FE->getUID()]; HFI.isModuleHeader = true; + HFI.isCompilingModuleHeader = isCompilingModuleHeader; } void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 3e7a44c0e35d..de234853fbf3 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -87,7 +87,7 @@ ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo) : LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo), - BuiltinIncludeDir(0) + BuiltinIncludeDir(0), CompilingModule(0) { IntrusiveRefCntPtr DiagIDs(new DiagnosticIDs); Diags = IntrusiveRefCntPtr( @@ -388,8 +388,13 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, // Create a new module with this name. Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, IsExplicit); - if (!Parent) + if (!Parent) { Modules[Name] = Result; + if (!LangOpts.CurrentModule.empty() && !CompilingModule && + Name == LangOpts.CurrentModule) { + CompilingModule = Result; + } + } return std::make_pair(Result, true); } @@ -605,7 +610,8 @@ void ModuleMap::addHeader(Module *Mod, const FileEntry *Header, Mod->ExcludedHeaders.push_back(Header); } else { Mod->Headers.push_back(Header); - HeaderInfo.MarkFileModuleHeader(Header); + bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule; + HeaderInfo.MarkFileModuleHeader(Header, isCompilingModuleHeader); } Headers[Header] = KnownHeader(Mod, Excluded); } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index b8ada04e5d8a..a96ecd7b86c2 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1542,6 +1542,8 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) { const HeaderFileInfo &HFI = HS.getFileInfo(File); if (HFI.External && Chain) continue; + if (HFI.isModuleHeader && !HFI.isCompilingModuleHeader) + continue; // Turn the file name into an absolute path, if it isn't already. const char *Filename = File->getName(); diff --git a/clang/test/Modules/self-import-header/af.framework/Headers/a1.h b/clang/test/Modules/self-import-header/af.framework/Headers/a1.h new file mode 100644 index 000000000000..31ae279bde2d --- /dev/null +++ b/clang/test/Modules/self-import-header/af.framework/Headers/a1.h @@ -0,0 +1,4 @@ +@import DepBuiltin; + +@interface Foo +@end diff --git a/clang/test/Modules/self-import-header/af.framework/Headers/a2.h b/clang/test/Modules/self-import-header/af.framework/Headers/a2.h new file mode 100644 index 000000000000..cc7e6e20b667 --- /dev/null +++ b/clang/test/Modules/self-import-header/af.framework/Headers/a2.h @@ -0,0 +1 @@ +#import "a1.h" diff --git a/clang/test/Modules/self-import-header/af.framework/module.map b/clang/test/Modules/self-import-header/af.framework/module.map new file mode 100644 index 000000000000..87176831df2d --- /dev/null +++ b/clang/test/Modules/self-import-header/af.framework/module.map @@ -0,0 +1,4 @@ +framework module af { + header "a1.h" + header "a2.h" +} diff --git a/clang/test/Modules/self-import-header/depend_builtin/h1.h b/clang/test/Modules/self-import-header/depend_builtin/h1.h new file mode 100644 index 000000000000..13298efce877 --- /dev/null +++ b/clang/test/Modules/self-import-header/depend_builtin/h1.h @@ -0,0 +1 @@ +#include diff --git a/clang/test/Modules/self-import-header/depend_builtin/module.map b/clang/test/Modules/self-import-header/depend_builtin/module.map new file mode 100644 index 000000000000..a736ad85c136 --- /dev/null +++ b/clang/test/Modules/self-import-header/depend_builtin/module.map @@ -0,0 +1,5 @@ +module DepBuiltin { +header "h1.h" + export * +} + diff --git a/clang/test/Modules/self-import-header/test.m b/clang/test/Modules/self-import-header/test.m new file mode 100644 index 000000000000..52cae7ebff11 --- /dev/null +++ b/clang/test/Modules/self-import-header/test.m @@ -0,0 +1,7 @@ +// rdar://13840148 + +// RUN: rm -rf %t +// RUN: %clang -fsyntax-only -isysroot %S/../Inputs/System/usr/include -fmodules -fmodules-cache-path=%t \ +// RUN: -F %S -I %S %s -D__need_wint_t -Werror=implicit-function-declaration + +@import af;