Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -210,6 +210,7 @@ def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleConflict : DiagGroup<"module-conflict">; +def NeedImport : DiagGroup<"need-import">; def NewlineEOF : DiagGroup<"newline-eof">; def NullArithmetic : DiagGroup<"null-arithmetic">; def NullCharacter : DiagGroup<"null-character">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6846,6 +6846,9 @@ "declaration of %0 must be imported from module '%1' before it is required">; def err_module_private_definition : Error< "definition of %0 must be imported from module '%1' before it is required">; +def warn_need_module_import : Warning< + "use of identifier '%0' requires import/inclusion of the module '%1'">, + InGroup; } let CategoryName = "Documentation Issue" in { Index: include/clang/Basic/LangOptions.def =================================================================== --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -95,6 +95,7 @@ BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") LANGOPT(Modules , 1, 0, "modules extension to C") LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") +LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references") LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -578,6 +578,9 @@ def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">; +def fmodules_search_all : Flag <["-"], "fmodules-search-all">, Group, + Flags<[DriverOption, CC1Option]>, + HelpText<"Search even non-imported modules to resolve references">; def fmodules : Flag <["-"], "fmodules">, Group, Flags<[DriverOption, CC1Option]>, HelpText<"Enable the 'modules' language feature">; @@ -654,6 +657,9 @@ Flags<[DriverOption]>; def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group, Flags<[DriverOption]>; +def fno_modules_search_all : Flag <["-"], "fno-modules-search-all">, Group, + Flags<[DriverOption, CC1Option]>, + HelpText<"Inhibit search of non-imported modules to resolve references">; def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group; def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group; def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group; Index: include/clang/Frontend/ASTUnit.h =================================================================== --- include/clang/Frontend/ASTUnit.h +++ include/clang/Frontend/ASTUnit.h @@ -873,6 +873,8 @@ SourceLocation ImportLoc, bool Complain) { } + + GlobalModuleIndex *loadGlobalModuleIndex() { return 0; } }; } // namespace clang Index: include/clang/Frontend/CompilerInstance.h =================================================================== --- include/clang/Frontend/CompilerInstance.h +++ include/clang/Frontend/CompilerInstance.h @@ -118,6 +118,9 @@ /// have finished with this translation unit. bool BuildGlobalModuleIndex; + /// \brief We have a full global module index, with all modules. + bool HaveFullGlobalModuleIndex; + /// \brief One or more modules failed to build. bool ModuleBuildFailed; @@ -658,7 +661,10 @@ const FrontendOptions &Opts); /// } - + + // Create module manager. + void createModuleManager(); + virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, @@ -673,6 +679,8 @@ return ModuleLoader::HadFatalFailure; } + virtual GlobalModuleIndex *loadGlobalModuleIndex(); + }; } // end namespace clang Index: include/clang/Lex/HeaderSearch.h =================================================================== --- include/clang/Lex/HeaderSearch.h +++ include/clang/Lex/HeaderSearch.h @@ -494,6 +494,13 @@ /// /// \returns The module with the given name. Module *lookupModule(StringRef ModuleName, bool AllowSearch = true); + + /// \brief Lookup a top level module given its file name. + /// + /// \param ModuleFileName The name of the module file. + /// + /// \returns The module with the given name. + Module *lookupModuleFromFile(StringRef ModuleFileName); void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } Index: include/clang/Lex/ModuleLoader.h =================================================================== --- include/clang/Lex/ModuleLoader.h +++ include/clang/Lex/ModuleLoader.h @@ -21,6 +21,7 @@ namespace clang { +class GlobalModuleIndex; class IdentifierInfo; class Module; @@ -88,6 +89,17 @@ SourceLocation ImportLoc, bool Complain) = 0; + /// \brief Load, create, or return global module. + /// This function returns an existing global module index, if one + /// had already been loaded or created, or loads one if it + /// exists, or creates one if it doesn't exist. + /// Also, importantly, if the index doesn't cover all the modules + /// in the module map, it will be update to do so here, because + /// of its use in searching for needed module imports and + /// associated fixit messages. + /// \returns Returns null if load failed. + virtual GlobalModuleIndex *loadGlobalModuleIndex() = 0; + bool HadFatalFailure; }; Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1322,6 +1322,18 @@ bool IsCtorOrDtorName = false, bool WantNontrivialTypeSourceInfo = false, IdentifierInfo **CorrectedII = 0); + + // Calls getTypeName, and if not found, will search for a module with the + // type, implicitly importing it and displaying a fixit message. + ParsedType getTypeNameWithModuleCheck(const IdentifierInfo &II, + SourceLocation NameLoc, + Scope *S, CXXScopeSpec *SS = 0, + bool isClassName = false, + bool HasTrailingDot = false, + ParsedType ObjectType = ParsedType(), + bool IsCtorOrDtorName = false, + bool WantNontrivialTypeSourceInfo = false, + IdentifierInfo **CorrectedII = 0); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S); bool DiagnoseUnknownTypeName(IdentifierInfo *&II, Index: include/clang/Serialization/ASTReader.h =================================================================== --- include/clang/Serialization/ASTReader.h +++ include/clang/Serialization/ASTReader.h @@ -1256,6 +1256,12 @@ /// \brief Determine whether this AST reader has a global index. bool hasGlobalIndex() const { return GlobalIndex.isValid(); } + /// \brief Return global module index. + GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); } + + /// \brief Reset reader for a reload try. + void resetForReload() { TriedLoadingGlobalIndex = false; } + /// \brief Attempts to load the global index. /// /// \returns true if loading the global index has failed for any reason. Index: include/clang/Serialization/GlobalModuleIndex.h =================================================================== --- include/clang/Serialization/GlobalModuleIndex.h +++ include/clang/Serialization/GlobalModuleIndex.h @@ -186,6 +186,9 @@ /// \brief Print statistics to standard error. void printStats(); + /// \brief Print debugging view to standard error. + void dump(); + /// \brief Write a global index into the given /// /// \param FileMgr The file manager to use to load module files. Index: lib/Frontend/CompilerInstance.cpp =================================================================== --- lib/Frontend/CompilerInstance.cpp +++ lib/Frontend/CompilerInstance.cpp @@ -31,6 +31,7 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/GlobalModuleIndex.h" #include "llvm/ADT/Statistic.h" #include "llvm/Config/config.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -51,7 +52,8 @@ CompilerInstance::CompilerInstance() : Invocation(new CompilerInvocation()), ModuleManager(0), - BuildGlobalModuleIndex(false), ModuleBuildFailed(false) { + BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), + ModuleBuildFailed(false) { } CompilerInstance::~CompilerInstance() { @@ -1094,6 +1096,43 @@ } } +void CompilerInstance::createModuleManager() { + if (!ModuleManager) { + if (!hasASTContext()) + createASTContext(); + + // If we're not recursively building a module, check whether we + // need to prune the module cache. + if (getSourceManager().getModuleBuildStack().empty() && + getHeaderSearchOpts().ModuleCachePruneInterval > 0 && + getHeaderSearchOpts().ModuleCachePruneAfter > 0) { + pruneModuleCache(getHeaderSearchOpts()); + } + + std::string Sysroot = getHeaderSearchOpts().Sysroot; + const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + ModuleManager = new ASTReader(getPreprocessor(), *Context, + Sysroot.empty() ? "" : Sysroot.c_str(), + PPOpts.DisablePCHValidation, + /*AllowASTWithCompilerErrors=*/false, + getFrontendOpts().UseGlobalModuleIndex); + if (hasASTConsumer()) { + ModuleManager->setDeserializationListener( + getASTConsumer().GetASTDeserializationListener()); + getASTContext().setASTMutationListener( + getASTConsumer().GetASTMutationListener()); + } + + OwningPtr Source; + Source.reset(ModuleManager); + getASTContext().setExternalSource(Source); + if (hasSema()) + ModuleManager->InitializeSema(getSema()); + if (hasASTConsumer()) + ModuleManager->StartTranslationUnit(&getASTConsumer()); + } +} + ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, @@ -1141,37 +1180,7 @@ // If we don't already have an ASTReader, create one now. if (!ModuleManager) { - if (!hasASTContext()) - createASTContext(); - - // If we're not recursively building a module, check whether we - // need to prune the module cache. - if (getSourceManager().getModuleBuildStack().empty() && - getHeaderSearchOpts().ModuleCachePruneInterval > 0 && - getHeaderSearchOpts().ModuleCachePruneAfter > 0) { - pruneModuleCache(getHeaderSearchOpts()); - } - - std::string Sysroot = getHeaderSearchOpts().Sysroot; - const PreprocessorOptions &PPOpts = getPreprocessorOpts(); - ModuleManager = new ASTReader(getPreprocessor(), *Context, - Sysroot.empty() ? "" : Sysroot.c_str(), - PPOpts.DisablePCHValidation, - /*AllowASTWithCompilerErrors=*/false, - getFrontendOpts().UseGlobalModuleIndex); - if (hasASTConsumer()) { - ModuleManager->setDeserializationListener( - getASTConsumer().GetASTDeserializationListener()); - getASTContext().setASTMutationListener( - getASTConsumer().GetASTMutationListener()); - } - OwningPtr Source; - Source.reset(ModuleManager); - getASTContext().setExternalSource(Source); - if (hasSema()) - ModuleManager->InitializeSema(getSema()); - if (hasASTConsumer()) - ModuleManager->StartTranslationUnit(&getASTConsumer()); + createModuleManager(); } // Try to load the module file. @@ -1396,3 +1405,59 @@ ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); } +GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex() { + if (!ModuleManager) + createModuleManager(); + // Can't do anything if we don't have the module manager. + if (!ModuleManager) + return 0; + // Get an existing global index. This load it if not already + // loaded. + ModuleManager->loadGlobalIndex(); + GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); + // If the global index doesn't exist, create it. + if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && + hasPreprocessor()) { + llvm::sys::fs::create_directories( + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + GlobalModuleIndex::writeIndex( + getFileManager(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + ModuleManager->resetForReload(); + ModuleManager->loadGlobalIndex(); + GlobalIndex = ModuleManager->getGlobalIndex(); + } + // For finding modules needing to be imported for fixit messages, + // we need to make the global index cover all modules, so we do that here. + if (!HaveFullGlobalModuleIndex && GlobalIndex) { + ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); + bool recreateIndex = false; + for (ModuleMap::module_iterator I = MMap.module_begin(), + E = MMap.module_end(); I != E; ++I) { + Module *TheModule = I->second; + const FileEntry *Entry = TheModule->getASTFile(); + if (!Entry) { + SourceLocation dummyLoc; + SmallVector, 2> Path; + for (Module *Mod = TheModule; Mod; Mod = Mod->Parent) + Path.push_back(std::make_pair( + getPreprocessor().getIdentifierInfo(Mod->Name), Mod->DefinitionLoc)); + std::reverse(Path.begin(), Path.end()); + // Load a module as hidden. This also adds it to the global index. + ModuleLoadResult Result = loadModule(TheModule->DefinitionLoc, Path, + Module::Hidden, false); + recreateIndex = true; + } + } + if (recreateIndex) { + GlobalModuleIndex::writeIndex( + getFileManager(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + ModuleManager->resetForReload(); + ModuleManager->loadGlobalIndex(); + GlobalIndex = ModuleManager->getGlobalIndex(); + } + HaveFullGlobalModuleIndex = true; + } + return GlobalIndex; +} Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1324,6 +1324,9 @@ Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.Modules = Args.hasArg(OPT_fmodules); Opts.ModulesDeclUse = Args.hasArg(OPT_fmodules_decluse); + Opts.ModulesSearchAll = Opts.Modules && + (!Args.hasArg(OPT_fno_modules_search_all) || + Args.hasArg(OPT_fmodules_search_all)); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); Index: lib/Lex/HeaderSearch.cpp =================================================================== --- lib/Lex/HeaderSearch.cpp +++ lib/Lex/HeaderSearch.cpp @@ -204,6 +204,10 @@ return Module; } +Module *HeaderSearch::lookupModuleFromFile(StringRef ModuleFileName) { + return lookupModule(llvm::sys::path::stem(ModuleFileName), false); +} + //===----------------------------------------------------------------------===// // File lookup within a DirectoryLookup scope //===----------------------------------------------------------------------===// @@ -690,6 +694,17 @@ } } + // If no includers (as in case of module build), and not an angled + // include, do a final check in the current directory + if (Includers.empty() && !isAngled && !NoCurDirSearch) { + const FileEntry *Result = FileMgr.getFile(Filename, /*openFile=*/true); + if (Result) { + CacheLookup.second + = LookupFileCache.GetOrCreateValue(Filename).getValue().second; + return Result; + } + } + // Otherwise, didn't find it. Remember we didn't find this. CacheLookup.second = SearchDirs.size(); return 0; Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -2766,7 +2766,7 @@ goto DoneWithDeclSpec; ParsedType TypeRep = - Actions.getTypeName(*Tok.getIdentifierInfo(), + Actions.getTypeNameWithModuleCheck(*Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope()); // If this is not a typedef name, don't parse it as part of the declspec, Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -25,6 +25,7 @@ #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" +#include "clang/Basic/Module.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -41,6 +42,8 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Template.h" +#include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/Module.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" #include @@ -338,6 +341,79 @@ return ParsedType::make(T); } +// Calls getTypeName, and if not found, will search for a module with the +// type, implicitly importing it and displaying a fixit message. +// FIXME: Apparently, the global index only finds top-level modules, so +// perhaps this isn't the right implementation, but it's a starting point, +// and given the fixit message output, the user can probably figure out the +// right import statement. +// FIXME: Can we figure out the submodule from the type and refine the +// visibility to just the submodule? +// FIXME: Can we figure out where to put the fixit import/include? +ParsedType Sema::getTypeNameWithModuleCheck(const IdentifierInfo &II, + SourceLocation NameLoc, + Scope *S, CXXScopeSpec *SS, + bool isClassName, + bool HasTrailingDot, + ParsedType ObjectType, + bool IsCtorOrDtorName, + bool WantNontrivialTypeSourceInfo, + IdentifierInfo **CorrectedII) { + // Do main look up, before checking non-imported modules. + ParsedType TypeRep = getTypeName(II, NameLoc, S, SS, isClassName, + HasTrailingDot, ObjectType, IsCtorOrDtorName, + WantNontrivialTypeSourceInfo, CorrectedII); + + // If found exit now with the type. Also exit if modules not enabled. + if (TypeRep || !getLangOpts().Modules || !getLangOpts().ModulesSearchAll) + return TypeRep; + + // Otherwise try to find the type in modules via the global module index. + ModuleLoader &Loader = PP.getModuleLoader(); + GlobalModuleIndex *GlobalIndex = Loader.loadGlobalModuleIndex(); + + if (!GlobalIndex) + return TypeRep; + + GlobalModuleIndex::HitSet FoundModules; + + // Find the modules that reference the identifier. + if (GlobalIndex->lookupIdentifier(II.getName(), FoundModules)) { + // Walk the found modules that reference the identifier. + for (GlobalModuleIndex::HitSet::iterator I = FoundModules.begin(), + E = FoundModules.end(); I != E; ++I) { + ModuleFile *TheModuleFile = *I; + // Find the module from the file name. + Module *TheModule = PP.getHeaderSearchInfo().lookupModuleFromFile( + TheModuleFile->FileName); + assert(TheModule && "Should be able to find the module."); + // Make the module visible so we can repeat the type lookup. + Loader.makeModuleVisible(TheModule, Module::AllVisible, NameLoc, false); + // Try the type lookup again. + TypeRep = getTypeName(II, NameLoc, S, SS, isClassName, + HasTrailingDot, ObjectType, IsCtorOrDtorName, + WantNontrivialTypeSourceInfo, CorrectedII); + // If we found the type, display a fixit warning and exit. + if (TypeRep) { + // FIXME: Can we figure out the submodule from the type and refine + // the visibility to just the submodule? + std::string fixit = "#import "; + fixit += TheModule->Name; + // FIXME: Figure out how to find the right insertion point, + // For now we just use the type location. + Diag(NameLoc, diag::warn_need_module_import) + << II.getName() << TheModule->getFullModuleName() << + FixItHint::CreateInsertion(NameLoc, fixit); + break; + } + // Otherwise hide the module. + Loader.makeModuleVisible(TheModule, Module::Hidden, NameLoc, false); + } + } + + return TypeRep; +} + /// isTagName() - This method is called *for error recovery purposes only* /// to determine if the specified name is a valid tag name ("struct foo"). If /// so, this returns the TST for the tag corresponding to it (TST_enum, Index: lib/Serialization/GlobalModuleIndex.cpp =================================================================== --- lib/Serialization/GlobalModuleIndex.cpp +++ lib/Serialization/GlobalModuleIndex.cpp @@ -341,6 +341,21 @@ std::fprintf(stderr, "\n"); } +void GlobalModuleIndex::dump() { + std::fprintf(stderr, "*** Global Module Index Dump:\n"); + std::fprintf(stderr, "Module files:\n"); + for (llvm::SmallVector::iterator I = Modules.begin(), + E = Modules.end(); I != E; ++I) { + ModuleInfo *MI = (ModuleInfo*)I; + std::fprintf(stderr, "** %s\n", MI->FileName.c_str()); + if (MI->File) + MI->File->dump(); + else + std::fprintf(stderr, "\n"); + } + std::fprintf(stderr, "\n"); +} + //----------------------------------------------------------------------------// // Global module index writer. //----------------------------------------------------------------------------// Index: test/Modules/Inputs/undefined-type-fixit/module.map =================================================================== --- test/Modules/Inputs/undefined-type-fixit/module.map +++ test/Modules/Inputs/undefined-type-fixit/module.map @@ -0,0 +1,9 @@ +module public1 { + header "public1.h" +} +module public2 { + header "public2.h" + module public2sub { + header "public2sub.h" + } +} Index: test/Modules/Inputs/undefined-type-fixit/public1.h =================================================================== --- test/Modules/Inputs/undefined-type-fixit/public1.h +++ test/Modules/Inputs/undefined-type-fixit/public1.h @@ -0,0 +1,6 @@ +#ifndef PUBLIC1_H +#define PUBLIC1_H + +struct use_this1 { int field; }; + +#endif Index: test/Modules/Inputs/undefined-type-fixit/public2.h =================================================================== --- test/Modules/Inputs/undefined-type-fixit/public2.h +++ test/Modules/Inputs/undefined-type-fixit/public2.h @@ -0,0 +1,6 @@ +#ifndef PUBLIC2_H +#define PUBLIC2_H + +struct use_this2 { int field; }; + +#endif Index: test/Modules/Inputs/undefined-type-fixit/public2sub.h =================================================================== --- test/Modules/Inputs/undefined-type-fixit/public2sub.h +++ test/Modules/Inputs/undefined-type-fixit/public2sub.h @@ -0,0 +1,6 @@ +#ifndef PUBLIC2SUB_H +#define PUBLIC2SUB_H + +struct use_this2sub { int field; }; + +#endif Index: test/Modules/auto-module-import.m =================================================================== --- test/Modules/auto-module-import.m +++ test/Modules/auto-module-import.m @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify -DERRORS -// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify +// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fno-modules-search-all -F %S/Inputs %s -verify -DERRORS +// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -fno-modules-search-all -F %S/Inputs %s -verify // // Test both with and without the declarations that refer to unimported // entities. For error recovery, those cases implicitly trigger an import. Index: test/Modules/cxx-inline-namespace.cpp =================================================================== --- test/Modules/cxx-inline-namespace.cpp +++ test/Modules/cxx-inline-namespace.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 +// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-search-all -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 @import cxx_inline_namespace; Index: test/Modules/cxx-linkage-cache.cpp =================================================================== --- test/Modules/cxx-linkage-cache.cpp +++ test/Modules/cxx-linkage-cache.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 +// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-search-all -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 @import cxx_linkage_cache; Index: test/Modules/decldef.m =================================================================== --- test/Modules/decldef.m +++ test/Modules/decldef.m @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify // expected-note@Inputs/def.h:5 {{previous}} Index: test/Modules/decldef.mm =================================================================== --- test/Modules/decldef.mm +++ test/Modules/decldef.mm @@ -1,6 +1,6 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY -// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify // expected-note@Inputs/def.h:5 {{previous}} Index: test/Modules/module-private.cpp =================================================================== --- test/Modules/module-private.cpp +++ test/Modules/module-private.cpp @@ -1,7 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_left -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_right -emit-module %S/Inputs/module.map -// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_left -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_right -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fno-modules-search-all -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify // FIXME: When we have a syntax for modules in C++, use that. @import module_private_left; Index: test/Modules/submodules.cpp =================================================================== --- test/Modules/submodules.cpp +++ test/Modules/submodules.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -I %S/Inputs/submodules %s -verify +// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fno-modules-search-all -I %S/Inputs/submodules %s -verify // FIXME: When we have a syntax for modules in C++, use that. @import std.vector; Index: test/Modules/undefined-type-fixit1.cpp =================================================================== --- test/Modules/undefined-type-fixit1.cpp +++ test/Modules/undefined-type-fixit1.cpp @@ -0,0 +1,10 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -I %S/Inputs/undefined-type-fixit %s -verify + +//#include "public1.h" +#include "public2.h" +#include "public2sub.h" + +use_this1 client_variable1; // expected-warning {{Use of identifier 'use_this1' requires import/inclusion of the module 'public1'}} +use_this2 client_variable2; +use_this2sub client_variable2sub; Index: unittests/Basic/SourceManagerTest.cpp =================================================================== --- unittests/Basic/SourceManagerTest.cpp +++ unittests/Basic/SourceManagerTest.cpp @@ -63,6 +63,8 @@ Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) { } + + virtual GlobalModuleIndex *loadGlobalModuleIndex() { return 0; } }; TEST_F(SourceManagerTest, isBeforeInTranslationUnit) { Index: unittests/Lex/CMakeLists.txt =================================================================== --- unittests/Lex/CMakeLists.txt +++ unittests/Lex/CMakeLists.txt @@ -14,4 +14,5 @@ clangLex clangParse clangSema + clangSerialization ) Index: unittests/Lex/LexerTest.cpp =================================================================== --- unittests/Lex/LexerTest.cpp +++ unittests/Lex/LexerTest.cpp @@ -40,6 +40,8 @@ Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) { } + + virtual GlobalModuleIndex *loadGlobalModuleIndex() { return 0; } }; // The test fixture. Index: unittests/Lex/Makefile =================================================================== --- unittests/Lex/Makefile +++ unittests/Lex/Makefile @@ -9,8 +9,8 @@ CLANG_LEVEL = ../.. TESTNAME = Lex -LINK_COMPONENTS := mcparser support mc +LINK_COMPONENTS := mcparser support mc bitreader USEDLIBS = clangParse.a clangSema.a clangAnalysis.a clangEdit.a \ - clangAST.a clangLex.a clangBasic.a + clangSerialization.a clangAST.a clangLex.a clangBasic.a include $(CLANG_LEVEL)/unittests/Makefile Index: unittests/Lex/PPCallbacksTest.cpp =================================================================== --- unittests/Lex/PPCallbacksTest.cpp +++ unittests/Lex/PPCallbacksTest.cpp @@ -45,6 +45,8 @@ Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) { } + + virtual GlobalModuleIndex *loadGlobalModuleIndex() { return 0; } }; // Stub to collect data from InclusionDirective callbacks. Index: unittests/Lex/PPConditionalDirectiveRecordTest.cpp =================================================================== --- unittests/Lex/PPConditionalDirectiveRecordTest.cpp +++ unittests/Lex/PPConditionalDirectiveRecordTest.cpp @@ -64,6 +64,8 @@ Module::NameVisibilityKind Visibility, SourceLocation ImportLoc, bool Complain) { } + + virtual GlobalModuleIndex *loadGlobalModuleIndex() { return 0; } }; TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {