1636404a3SDaniel Dunbar //===--- CompilerInstance.cpp ---------------------------------------------===// 2636404a3SDaniel Dunbar // 3636404a3SDaniel Dunbar // The LLVM Compiler Infrastructure 4636404a3SDaniel Dunbar // 5636404a3SDaniel Dunbar // This file is distributed under the University of Illinois Open Source 6636404a3SDaniel Dunbar // License. See LICENSE.TXT for details. 7636404a3SDaniel Dunbar // 8636404a3SDaniel Dunbar //===----------------------------------------------------------------------===// 9636404a3SDaniel Dunbar 10636404a3SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h" 1156d9c293SDaniel Dunbar #include "clang/AST/ASTConsumer.h" 12df3e30c4SDaniel Dunbar #include "clang/AST/ASTContext.h" 13bcfc7d02SDouglas Gregor #include "clang/AST/Decl.h" 14636404a3SDaniel Dunbar #include "clang/Basic/Diagnostic.h" 15546a676aSDaniel Dunbar #include "clang/Basic/FileManager.h" 16546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h" 17636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h" 184f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h" 198b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h" 204f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h" 21faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h" 22f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h" 232083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h" 244610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h" 257d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h" 26aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h" 273a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h" 283a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h" 293a02247dSChandler Carruth #include "clang/Lex/PTHManager.h" 303a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h" 31f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h" 323a02247dSChandler Carruth #include "clang/Sema/Sema.h" 333a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h" 34171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h" 353a02247dSChandler Carruth #include "llvm/Config/config.h" 363a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h" 373a02247dSChandler Carruth #include "llvm/Support/FileSystem.h" 388aaf4995SMichael J. Spencer #include "llvm/Support/Host.h" 39e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h" 403a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h" 418aaf4995SMichael J. Spencer #include "llvm/Support/Path.h" 428aaf4995SMichael J. Spencer #include "llvm/Support/Program.h" 438aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h" 443a02247dSChandler Carruth #include "llvm/Support/Timer.h" 453a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 46f25faaafSMichael J. Spencer #include "llvm/Support/system_error.h" 47527b1c95SDouglas Gregor #include <sys/stat.h> 4837da327cSDouglas Gregor #include <time.h> 4954a88810SDouglas Gregor 50636404a3SDaniel Dunbar using namespace clang; 51636404a3SDaniel Dunbar 52e922d9bdSDaniel Dunbar CompilerInstance::CompilerInstance() 535e306b12SDouglas Gregor : Invocation(new CompilerInvocation()), ModuleManager(0), 54c1bbec85SDouglas Gregor BuildGlobalModuleIndex(false), ModuleBuildFailed(false) { 55636404a3SDaniel Dunbar } 56636404a3SDaniel Dunbar 57636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 583c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 59e922d9bdSDaniel Dunbar } 60e922d9bdSDaniel Dunbar 6168242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) { 625e14d39aSTed Kremenek Invocation = Value; 6368242254SDaniel Dunbar } 6468242254SDaniel Dunbar 65c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 66e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 6711ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 6811ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 69e060e57bSDouglas Gregor !ModuleBuildFailed; 70c1bbec85SDouglas Gregor } 71c1bbec85SDouglas Gregor 729c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 737f95d26eSDouglas Gregor Diagnostics = Value; 74e01dc86dSDaniel Dunbar } 75e01dc86dSDaniel Dunbar 76e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) { 775e14d39aSTed Kremenek Target = Value; 78e01dc86dSDaniel Dunbar } 79e01dc86dSDaniel Dunbar 80e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) { 815e14d39aSTed Kremenek FileMgr = Value; 82e01dc86dSDaniel Dunbar } 83e01dc86dSDaniel Dunbar 84e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) { 855e14d39aSTed Kremenek SourceMgr = Value; 86e01dc86dSDaniel Dunbar } 87e01dc86dSDaniel Dunbar 885e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 89e01dc86dSDaniel Dunbar 905e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; } 91e01dc86dSDaniel Dunbar 920e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 930e93f017SDouglas Gregor TheSema.reset(S); 940e93f017SDouglas Gregor } 950e93f017SDouglas Gregor 9656d9c293SDaniel Dunbar void CompilerInstance::setASTConsumer(ASTConsumer *Value) { 9756d9c293SDaniel Dunbar Consumer.reset(Value); 9856d9c293SDaniel Dunbar } 9956d9c293SDaniel Dunbar 100e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 101e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 102e01dc86dSDaniel Dunbar } 103e01dc86dSDaniel Dunbar 1047d75afc5SDaniel Dunbar // Diagnostics 105811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 1067b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 1079c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 1082083c32fSDaniel Dunbar std::string ErrorInfo; 1092083c32fSDaniel Dunbar bool OwnsStream = false; 1100e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 111811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 1122083c32fSDaniel Dunbar // Create the output stream. 1132083c32fSDaniel Dunbar llvm::raw_fd_ostream *FileOS( 11416125fb6SRafael Espindola new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo, 11516125fb6SRafael Espindola llvm::sys::fs::F_Append)); 1162083c32fSDaniel Dunbar if (!ErrorInfo.empty()) { 1172083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 1182118a5cdSSean Silva << DiagOpts->DiagnosticLogFile << ErrorInfo; 1192083c32fSDaniel Dunbar } else { 1202083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 1212083c32fSDaniel Dunbar FileOS->SetUseAtomicWrites(true); 1222083c32fSDaniel Dunbar OS = FileOS; 1232083c32fSDaniel Dunbar OwnsStream = true; 1242083c32fSDaniel Dunbar } 1252083c32fSDaniel Dunbar } 1262083c32fSDaniel Dunbar 1272083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 1287b83306dSDaniel Dunbar LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, 1292083c32fSDaniel Dunbar OwnsStream); 1307b83306dSDaniel Dunbar if (CodeGenOpts) 1317b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 1328b00dcb0SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); 1332083c32fSDaniel Dunbar } 1342083c32fSDaniel Dunbar 135811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 1364610ea2bSTed Kremenek DiagnosticsEngine &Diags, 1374610ea2bSTed Kremenek StringRef OutputFile) { 1384610ea2bSTed Kremenek std::string ErrorInfo; 139e2778999SDylan Noblesmith OwningPtr<llvm::raw_fd_ostream> OS; 1404610ea2bSTed Kremenek OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, 14116125fb6SRafael Espindola llvm::sys::fs::F_Binary)); 1424610ea2bSTed Kremenek 1434610ea2bSTed Kremenek if (!ErrorInfo.empty()) { 1444610ea2bSTed Kremenek Diags.Report(diag::warn_fe_serialized_diag_failure) 1454610ea2bSTed Kremenek << OutputFile << ErrorInfo; 1464610ea2bSTed Kremenek return; 1474610ea2bSTed Kremenek } 1484610ea2bSTed Kremenek 1494610ea2bSTed Kremenek DiagnosticConsumer *SerializedConsumer = 1504548e044STed Kremenek clang::serialized_diags::create(OS.take(), DiagOpts); 1514610ea2bSTed Kremenek 1524610ea2bSTed Kremenek 1534610ea2bSTed Kremenek Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), 1544610ea2bSTed Kremenek SerializedConsumer)); 1554610ea2bSTed Kremenek } 1564610ea2bSTed Kremenek 157f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 15830071ceaSDouglas Gregor bool ShouldOwnClient) { 159f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 16030071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 1617d75afc5SDaniel Dunbar } 1627d75afc5SDaniel Dunbar 163c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 164811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 165e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 1662b9b4642SDouglas Gregor bool ShouldOwnClient, 1677b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 168c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 169c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 170811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 1711b39a2edSDaniel Dunbar 1727d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 1737d75afc5SDaniel Dunbar // implementing -verify. 174d0e9e3a6SDouglas Gregor if (Client) { 175d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 176d0e9e3a6SDouglas Gregor } else 1772dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 17850ec0da0SDaniel Dunbar 17950ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 180811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 18169609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 1827d75afc5SDaniel Dunbar 1832083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 184811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 1857b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 1862083c32fSDaniel Dunbar 187811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 1884610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 189811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 1904610ea2bSTed Kremenek 1917d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 192811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 1937d75afc5SDaniel Dunbar 1947f95d26eSDouglas Gregor return Diags; 1957d75afc5SDaniel Dunbar } 1967d75afc5SDaniel Dunbar 1977d75afc5SDaniel Dunbar // File Manager 1987d75afc5SDaniel Dunbar 199546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 2005e14d39aSTed Kremenek FileMgr = new FileManager(getFileSystemOpts()); 201546a676aSDaniel Dunbar } 202546a676aSDaniel Dunbar 2037d75afc5SDaniel Dunbar // Source Manager 2047d75afc5SDaniel Dunbar 2055159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 2065e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 207546a676aSDaniel Dunbar } 208aaa148fdSDaniel Dunbar 2097d75afc5SDaniel Dunbar // Preprocessor 2107d75afc5SDaniel Dunbar 211aaa148fdSDaniel Dunbar void CompilerInstance::createPreprocessor() { 21208142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 213aaa148fdSDaniel Dunbar 214aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 215aaa148fdSDaniel Dunbar PTHManager *PTHMgr = 0; 216d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 21708142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 218aaa148fdSDaniel Dunbar 219aaa148fdSDaniel Dunbar // Create the Preprocessor. 220b85b9ccbSDouglas Gregor HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 2211f76c4e8SManuel Klimek getSourceManager(), 2221fb5c3a6SDouglas Gregor getDiagnostics(), 22389929282SDouglas Gregor getLangOpts(), 22489929282SDouglas Gregor &getTarget()); 2251452ff15SDouglas Gregor PP = new Preprocessor(&getPreprocessorOpts(), 2261452ff15SDouglas Gregor getDiagnostics(), getLangOpts(), &getTarget(), 22708142534SDouglas Gregor getSourceManager(), *HeaderInfo, *this, PTHMgr, 228aaa148fdSDaniel Dunbar /*OwnsHeaderSearch=*/true); 229aaa148fdSDaniel Dunbar 230aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 231aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 232aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 233aaa148fdSDaniel Dunbar if (PTHMgr) { 23408142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 235aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 236aaa148fdSDaniel Dunbar } 237aaa148fdSDaniel Dunbar 2387f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 239f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 2407f6d60dcSDouglas Gregor 24108142534SDouglas Gregor InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); 242aaa148fdSDaniel Dunbar 24317441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 24417441589SJordan Rose 2451735f4e7SDouglas Gregor // Set up the module path, including the hash for the 2461735f4e7SDouglas Gregor // module-creation options. 2472c1dd271SDylan Noblesmith SmallString<256> SpecificModuleCache( 2481735f4e7SDouglas Gregor getHeaderSearchOpts().ModuleCachePath); 2491735f4e7SDouglas Gregor if (!getHeaderSearchOpts().DisableModuleHash) 2501735f4e7SDouglas Gregor llvm::sys::path::append(SpecificModuleCache, 2511735f4e7SDouglas Gregor getInvocation().getModuleHash()); 2522537a364SDouglas Gregor PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache); 2531735f4e7SDouglas Gregor 254aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 25508142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 256aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 257aaa148fdSDaniel Dunbar AttachDependencyFileGen(*PP, DepOpts); 2582e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 2592e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 26083d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 26183d46be3SDouglas Gregor 262aaa148fdSDaniel Dunbar 26327734fdbSDaniel Dunbar // Handle generating header include information, if requested. 26427734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 26527734fdbSDaniel Dunbar AttachHeaderIncludeGen(*PP); 2661af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 2670e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 2681af1d275SDaniel Dunbar if (OutputPath == "-") 2691af1d275SDaniel Dunbar OutputPath = ""; 270fe908a80SDaniel Dunbar AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, 271fe908a80SDaniel Dunbar /*ShowDepth=*/false); 2720fd6207dSHans Wennborg } 2730fd6207dSHans Wennborg 2740fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 2750fd6207dSHans Wennborg AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"", 2760fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 2771af1d275SDaniel Dunbar } 278aaa148fdSDaniel Dunbar } 279df3e30c4SDaniel Dunbar 280df3e30c4SDaniel Dunbar // ASTContext 281df3e30c4SDaniel Dunbar 282df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 283df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 2845e14d39aSTed Kremenek Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 285e8bbc121SDouglas Gregor &getTarget(), PP.getIdentifierTable(), 286df3e30c4SDaniel Dunbar PP.getSelectorTable(), PP.getBuiltinInfo(), 2875e14d39aSTed Kremenek /*size_reserve=*/ 0); 288df3e30c4SDaniel Dunbar } 289599313efSDaniel Dunbar 290599313efSDaniel Dunbar // ExternalASTSource 291599313efSDaniel Dunbar 2920e62c1ccSChris Lattner void CompilerInstance::createPCHExternalASTSource(StringRef Path, 29307a89a83SSebastian Redl bool DisablePCHValidation, 2944a280ff4SArgyrios Kyrtzidis bool AllowPCHWithCompilerErrors, 29507a89a83SSebastian Redl void *DeserializationListener){ 296e2778999SDylan Noblesmith OwningPtr<ExternalASTSource> Source; 297009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 298599313efSDaniel Dunbar Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, 299ce3a8293SDouglas Gregor DisablePCHValidation, 3004a280ff4SArgyrios Kyrtzidis AllowPCHWithCompilerErrors, 30107a89a83SSebastian Redl getPreprocessor(), getASTContext(), 302009e7f20SSebastian Redl DeserializationListener, 303c1bbec85SDouglas Gregor Preamble, 304c1bbec85SDouglas Gregor getFrontendOpts().UseGlobalModuleIndex)); 305925296b4SDouglas Gregor ModuleManager = static_cast<ASTReader*>(Source.get()); 306599313efSDaniel Dunbar getASTContext().setExternalSource(Source); 307599313efSDaniel Dunbar } 308599313efSDaniel Dunbar 309599313efSDaniel Dunbar ExternalASTSource * 3100e62c1ccSChris Lattner CompilerInstance::createPCHExternalASTSource(StringRef Path, 311599313efSDaniel Dunbar const std::string &Sysroot, 312ce3a8293SDouglas Gregor bool DisablePCHValidation, 3134a280ff4SArgyrios Kyrtzidis bool AllowPCHWithCompilerErrors, 314599313efSDaniel Dunbar Preprocessor &PP, 31507a89a83SSebastian Redl ASTContext &Context, 316009e7f20SSebastian Redl void *DeserializationListener, 317c1bbec85SDouglas Gregor bool Preamble, 318c1bbec85SDouglas Gregor bool UseGlobalModuleIndex) { 319e2778999SDylan Noblesmith OwningPtr<ASTReader> Reader; 3208835e03cSDouglas Gregor Reader.reset(new ASTReader(PP, Context, 321c567ba26SDouglas Gregor Sysroot.empty() ? "" : Sysroot.c_str(), 322d7c16b25SArgyrios Kyrtzidis DisablePCHValidation, 323c1bbec85SDouglas Gregor AllowPCHWithCompilerErrors, 324c1bbec85SDouglas Gregor UseGlobalModuleIndex)); 325599313efSDaniel Dunbar 32607a89a83SSebastian Redl Reader->setDeserializationListener( 3273e31c724SSebastian Redl static_cast<ASTDeserializationListener *>(DeserializationListener)); 328009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 329a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 3304b29c16eSDouglas Gregor : serialization::MK_PCH, 3312ec29367SArgyrios Kyrtzidis SourceLocation(), 3324b29c16eSDouglas Gregor ASTReader::ARR_None)) { 3332c499f65SSebastian Redl case ASTReader::Success: 334599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 335599313efSDaniel Dunbar // predefines buffer will be empty. 336599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 337599313efSDaniel Dunbar return Reader.take(); 338599313efSDaniel Dunbar 3392c499f65SSebastian Redl case ASTReader::Failure: 340599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 341599313efSDaniel Dunbar break; 342599313efSDaniel Dunbar 3437029ce1aSDouglas Gregor case ASTReader::Missing: 344c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 345c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 346c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 347c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 348599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 349599313efSDaniel Dunbar break; 350599313efSDaniel Dunbar } 351599313efSDaniel Dunbar 352599313efSDaniel Dunbar return 0; 353599313efSDaniel Dunbar } 354f7093b5aSDaniel Dunbar 355f7093b5aSDaniel Dunbar // Code Completion 356f7093b5aSDaniel Dunbar 3578e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 3588e984da8SDouglas Gregor const std::string &Filename, 3598e984da8SDouglas Gregor unsigned Line, 3608e984da8SDouglas Gregor unsigned Column) { 3618e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 3628e984da8SDouglas Gregor // line and column. 3635159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 3648e984da8SDouglas Gregor if (!Entry) { 3658e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 3668e984da8SDouglas Gregor << Filename; 3678e984da8SDouglas Gregor return true; 3688e984da8SDouglas Gregor } 3698e984da8SDouglas Gregor 3708e984da8SDouglas Gregor // Truncate the named file at the given line/column. 3718e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 3728e984da8SDouglas Gregor return false; 3738e984da8SDouglas Gregor } 3748e984da8SDouglas Gregor 375f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 376f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 3778e984da8SDouglas Gregor if (!CompletionConsumer) { 3782fca3c2cSErik Verbruggen setCodeCompletionConsumer( 379f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 380f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 3813292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 382f7093b5aSDaniel Dunbar llvm::outs())); 38300a0cf70SDouglas Gregor if (!CompletionConsumer) 38400a0cf70SDouglas Gregor return; 3858e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 3868e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 3872fca3c2cSErik Verbruggen setCodeCompletionConsumer(0); 3888e984da8SDouglas Gregor return; 3898e984da8SDouglas Gregor } 390f09935f1SDouglas Gregor 391f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 392a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 393f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 3942fca3c2cSErik Verbruggen setCodeCompletionConsumer(0); 395f09935f1SDouglas Gregor } 396f7093b5aSDaniel Dunbar } 397f7093b5aSDaniel Dunbar 3985505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 3995505dff8SKovarththanan Rajaratnam FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); 4005505dff8SKovarththanan Rajaratnam } 4015505dff8SKovarththanan Rajaratnam 402f7093b5aSDaniel Dunbar CodeCompleteConsumer * 403f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 404f7093b5aSDaniel Dunbar const std::string &Filename, 405f7093b5aSDaniel Dunbar unsigned Line, 406f7093b5aSDaniel Dunbar unsigned Column, 4073292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 4080e62c1ccSChris Lattner raw_ostream &OS) { 4098e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 410f7093b5aSDaniel Dunbar return 0; 411f7093b5aSDaniel Dunbar 412f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 4133292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 414f7093b5aSDaniel Dunbar } 415566eeb2dSDaniel Dunbar 41669f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 4170e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 4180e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 41969f74f80SDouglas Gregor TUKind, CompletionConsumer)); 4200e93f017SDouglas Gregor } 4210e93f017SDouglas Gregor 422566eeb2dSDaniel Dunbar // Output Files 423566eeb2dSDaniel Dunbar 424d0599970SArgyrios Kyrtzidis void CompilerInstance::addOutputFile(const OutputFile &OutFile) { 425d0599970SArgyrios Kyrtzidis assert(OutFile.OS && "Attempt to add empty stream to output list!"); 426d0599970SArgyrios Kyrtzidis OutputFiles.push_back(OutFile); 427566eeb2dSDaniel Dunbar } 428566eeb2dSDaniel Dunbar 4291c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 430d0599970SArgyrios Kyrtzidis for (std::list<OutputFile>::iterator 431566eeb2dSDaniel Dunbar it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) { 432d0599970SArgyrios Kyrtzidis delete it->OS; 433d0599970SArgyrios Kyrtzidis if (!it->TempFilename.empty()) { 434b5c356a4SAnders Carlsson if (EraseFiles) { 435b5c356a4SAnders Carlsson bool existed; 436b5c356a4SAnders Carlsson llvm::sys::fs::remove(it->TempFilename, existed); 437b5c356a4SAnders Carlsson } else { 4382c1dd271SDylan Noblesmith SmallString<128> NewOutFile(it->Filename); 439b5c356a4SAnders Carlsson 44071731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 44171731d6bSArgyrios Kyrtzidis // relative to that. 4429ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 443b5c356a4SAnders Carlsson if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename, 444b5c356a4SAnders Carlsson NewOutFile.str())) { 4453ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 446b5c356a4SAnders Carlsson << it->TempFilename << it->Filename << ec.message(); 447b5c356a4SAnders Carlsson 448b5c356a4SAnders Carlsson bool existed; 449b5c356a4SAnders Carlsson llvm::sys::fs::remove(it->TempFilename, existed); 450d0599970SArgyrios Kyrtzidis } 451d0599970SArgyrios Kyrtzidis } 452d0599970SArgyrios Kyrtzidis } else if (!it->Filename.empty() && EraseFiles) 453399ab33aSRafael Espindola llvm::sys::fs::remove(it->Filename); 454d0599970SArgyrios Kyrtzidis 455566eeb2dSDaniel Dunbar } 456566eeb2dSDaniel Dunbar OutputFiles.clear(); 457566eeb2dSDaniel Dunbar } 458566eeb2dSDaniel Dunbar 459420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 460420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary, 4610e62c1ccSChris Lattner StringRef InFile, 4620e62c1ccSChris Lattner StringRef Extension) { 463420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 464ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 465ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 466420b0f1bSDaniel Dunbar } 467420b0f1bSDaniel Dunbar 468420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 4690e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath, 470e326f9bbSDaniel Dunbar bool Binary, bool RemoveFileOnSignal, 4710e62c1ccSChris Lattner StringRef InFile, 47208a2bfd2SArgyrios Kyrtzidis StringRef Extension, 473b9c62c07SDaniel Dunbar bool UseTemporary, 474b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 475d0599970SArgyrios Kyrtzidis std::string Error, OutputPathName, TempPathName; 476420b0f1bSDaniel Dunbar llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary, 477e326f9bbSDaniel Dunbar RemoveFileOnSignal, 478420b0f1bSDaniel Dunbar InFile, Extension, 47908a2bfd2SArgyrios Kyrtzidis UseTemporary, 480b9c62c07SDaniel Dunbar CreateMissingDirectories, 481d0599970SArgyrios Kyrtzidis &OutputPathName, 482d0599970SArgyrios Kyrtzidis &TempPathName); 483420b0f1bSDaniel Dunbar if (!OS) { 4847554699aSDaniel Dunbar getDiagnostics().Report(diag::err_fe_unable_to_open_output) 4857554699aSDaniel Dunbar << OutputPath << Error; 4867554699aSDaniel Dunbar return 0; 487420b0f1bSDaniel Dunbar } 488420b0f1bSDaniel Dunbar 489420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 490420b0f1bSDaniel Dunbar // using stdin. 491d0599970SArgyrios Kyrtzidis addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 492d0599970SArgyrios Kyrtzidis TempPathName, OS)); 493420b0f1bSDaniel Dunbar 494420b0f1bSDaniel Dunbar return OS; 495420b0f1bSDaniel Dunbar } 496420b0f1bSDaniel Dunbar 497420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 4980e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath, 499420b0f1bSDaniel Dunbar std::string &Error, 500420b0f1bSDaniel Dunbar bool Binary, 501e326f9bbSDaniel Dunbar bool RemoveFileOnSignal, 5020e62c1ccSChris Lattner StringRef InFile, 5030e62c1ccSChris Lattner StringRef Extension, 50408a2bfd2SArgyrios Kyrtzidis bool UseTemporary, 505b9c62c07SDaniel Dunbar bool CreateMissingDirectories, 506d0599970SArgyrios Kyrtzidis std::string *ResultPathName, 507d0599970SArgyrios Kyrtzidis std::string *TempPathName) { 508b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 509b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 510b9c62c07SDaniel Dunbar 511d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 512420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 513420b0f1bSDaniel Dunbar OutFile = OutputPath; 514420b0f1bSDaniel Dunbar } else if (InFile == "-") { 515420b0f1bSDaniel Dunbar OutFile = "-"; 516420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 517399ab33aSRafael Espindola SmallString<128> Path(InFile); 518399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 519420b0f1bSDaniel Dunbar OutFile = Path.str(); 520420b0f1bSDaniel Dunbar } else { 521420b0f1bSDaniel Dunbar OutFile = "-"; 522420b0f1bSDaniel Dunbar } 523420b0f1bSDaniel Dunbar 524e2778999SDylan Noblesmith OwningPtr<llvm::raw_fd_ostream> OS; 52508a2bfd2SArgyrios Kyrtzidis std::string OSFile; 52608a2bfd2SArgyrios Kyrtzidis 52773c23a71SRafael Espindola if (UseTemporary) { 52873c23a71SRafael Espindola if (OutFile == "-") 52973c23a71SRafael Espindola UseTemporary = false; 53073c23a71SRafael Espindola else { 53173c23a71SRafael Espindola llvm::sys::fs::file_status Status; 53273c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 53373c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 53473c23a71SRafael Espindola // Fail early if we can't write to the final destination. 53573c23a71SRafael Espindola if (!llvm::sys::fs::can_write(OutputPath)) 53673c23a71SRafael Espindola return 0; 53773c23a71SRafael Espindola 53873c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 53973c23a71SRafael Espindola // things like '-o /dev/null' 54073c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 54173c23a71SRafael Espindola UseTemporary = false; 54273c23a71SRafael Espindola } 54373c23a71SRafael Espindola } 54473c23a71SRafael Espindola } 54573c23a71SRafael Espindola 54673c23a71SRafael Espindola if (UseTemporary) { 547d0599970SArgyrios Kyrtzidis // Create a temporary file. 5482c1dd271SDylan Noblesmith SmallString<128> TempPath; 54908a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 55008a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 55108a2bfd2SArgyrios Kyrtzidis int fd; 55218627115SRafael Espindola llvm::error_code EC = 55318627115SRafael Espindola llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 554157f34bdSRafael Espindola 555157f34bdSRafael Espindola if (CreateMissingDirectories && 5561d0912a4SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 557157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 558157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 559157f34bdSRafael Espindola if (!EC) { 56018627115SRafael Espindola EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 561157f34bdSRafael Espindola } 562157f34bdSRafael Espindola } 563157f34bdSRafael Espindola 564157f34bdSRafael Espindola if (!EC) { 56508a2bfd2SArgyrios Kyrtzidis OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 56608a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 56708a2bfd2SArgyrios Kyrtzidis } 56873c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 56973c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 57073c23a71SRafael Espindola // directory, but can write to the file. 571d0599970SArgyrios Kyrtzidis } 572d0599970SArgyrios Kyrtzidis 57308a2bfd2SArgyrios Kyrtzidis if (!OS) { 57408a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 57516125fb6SRafael Espindola OS.reset(new llvm::raw_fd_ostream( 57616125fb6SRafael Espindola OSFile.c_str(), Error, 57716125fb6SRafael Espindola (Binary ? llvm::sys::fs::F_Binary : llvm::sys::fs::F_None))); 5782eaef18eSDaniel Dunbar if (!Error.empty()) 579420b0f1bSDaniel Dunbar return 0; 58008a2bfd2SArgyrios Kyrtzidis } 581420b0f1bSDaniel Dunbar 582d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 583e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 58418556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 585d0599970SArgyrios Kyrtzidis 586420b0f1bSDaniel Dunbar if (ResultPathName) 587420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 588d0599970SArgyrios Kyrtzidis if (TempPathName) 589d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 590420b0f1bSDaniel Dunbar 5912eaef18eSDaniel Dunbar return OS.take(); 592420b0f1bSDaniel Dunbar } 593409e890fSDaniel Dunbar 594409e890fSDaniel Dunbar // Initialization Utilities 595409e890fSDaniel Dunbar 5961b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 5971b3240b0SArgyrios Kyrtzidis return InitializeSourceManager(Input, getDiagnostics(), 598a686e1b0SDouglas Gregor getFileManager(), getSourceManager(), 599a686e1b0SDouglas Gregor getFrontendOpts()); 600409e890fSDaniel Dunbar } 601409e890fSDaniel Dunbar 6021b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 6039c902b55SDavid Blaikie DiagnosticsEngine &Diags, 604409e890fSDaniel Dunbar FileManager &FileMgr, 605409e890fSDaniel Dunbar SourceManager &SourceMgr, 606409e890fSDaniel Dunbar const FrontendOptions &Opts) { 6071b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 608873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 6091b3240b0SArgyrios Kyrtzidis 6106566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 6116566e23eSArgyrios Kyrtzidis SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind); 6126566e23eSArgyrios Kyrtzidis assert(!SourceMgr.getMainFileID().isInvalid() && 6136566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 6146566e23eSArgyrios Kyrtzidis return true; 6156566e23eSArgyrios Kyrtzidis } 6166566e23eSArgyrios Kyrtzidis 6176566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 6186566e23eSArgyrios Kyrtzidis 6197c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 6207c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 6213841fa38SBenjamin Kramer const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 62252765215SDan Gohman if (!File) { 623409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 624409e890fSDaniel Dunbar return false; 625409e890fSDaniel Dunbar } 626e2951f48SDaniel Dunbar 627e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 628e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 6293841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 6303841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 6313841fa38SBenjamin Kramer // STDIN. 632e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 6333841fa38SBenjamin Kramer std::string ErrorStr; 6343841fa38SBenjamin Kramer if (llvm::MemoryBuffer *MB = 6353841fa38SBenjamin Kramer FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) { 636db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 637db0745abSDaniel Dunbar File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); 6383841fa38SBenjamin Kramer SourceMgr.overrideFileContents(File, MB); 6393841fa38SBenjamin Kramer } else { 6403841fa38SBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr; 6413841fa38SBenjamin Kramer return false; 6423841fa38SBenjamin Kramer } 643e2951f48SDaniel Dunbar } 644db0745abSDaniel Dunbar 645db0745abSDaniel Dunbar SourceMgr.createMainFileID(File, Kind); 646409e890fSDaniel Dunbar } else { 647e2778999SDylan Noblesmith OwningPtr<llvm::MemoryBuffer> SB; 6483841fa38SBenjamin Kramer if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) { 6493841fa38SBenjamin Kramer Diags.Report(diag::err_fe_error_reading_stdin) << ec.message(); 650409e890fSDaniel Dunbar return false; 651409e890fSDaniel Dunbar } 6522f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 6535159f616SChris Lattner SB->getBufferSize(), 0); 654a686e1b0SDouglas Gregor SourceMgr.createMainFileID(File, Kind); 655d9da7a1fSMichael J. Spencer SourceMgr.overrideFileContents(File, SB.take()); 656409e890fSDaniel Dunbar } 657409e890fSDaniel Dunbar 65852765215SDan Gohman assert(!SourceMgr.getMainFileID().isInvalid() && 65952765215SDan Gohman "Couldn't establish MainFileID!"); 660409e890fSDaniel Dunbar return true; 661409e890fSDaniel Dunbar } 6624f2bc55dSDaniel Dunbar 6634f2bc55dSDaniel Dunbar // High-Level Operations 6644f2bc55dSDaniel Dunbar 6654f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 6664f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 6674f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 6684f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 6694f2bc55dSDaniel Dunbar 6704f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 6714f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 6720e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 6734f2bc55dSDaniel Dunbar 6744f2bc55dSDaniel Dunbar // Create the target instance. 675f8715de5SDouglas Gregor setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts())); 6764f2bc55dSDaniel Dunbar if (!hasTarget()) 6774f2bc55dSDaniel Dunbar return false; 6784f2bc55dSDaniel Dunbar 6794f2bc55dSDaniel Dunbar // Inform the target of the language options. 6804f2bc55dSDaniel Dunbar // 6814f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 6824f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 6834f2bc55dSDaniel Dunbar getTarget().setForcedLangOptions(getLangOpts()); 6844f2bc55dSDaniel Dunbar 68529898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 68629898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 68729898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 68829898f45SFariborz Jahanian 6894f2bc55dSDaniel Dunbar // Validate/process some options. 6904f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 6914f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 6924f2bc55dSDaniel Dunbar << " based upon " << PACKAGE_STRING 6938188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 6944f2bc55dSDaniel Dunbar 6954f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 6964f2bc55dSDaniel Dunbar createFrontendTimer(); 6974f2bc55dSDaniel Dunbar 698171b780cSDouglas Gregor if (getFrontendOpts().ShowStats) 699171b780cSDouglas Gregor llvm::EnableStatistics(); 700171b780cSDouglas Gregor 7014f2bc55dSDaniel Dunbar for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 7024f2bc55dSDaniel Dunbar // Reset the ID tables if we are reusing the SourceManager. 703aed46fcbSDaniel Dunbar if (hasSourceManager()) 7044f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 7054f2bc55dSDaniel Dunbar 70632fbe312SDouglas Gregor if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 7074f2bc55dSDaniel Dunbar Act.Execute(); 7084f2bc55dSDaniel Dunbar Act.EndSourceFile(); 7094f2bc55dSDaniel Dunbar } 7104f2bc55dSDaniel Dunbar } 7114f2bc55dSDaniel Dunbar 7127910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 7137910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 7147910d7b7SArgyrios Kyrtzidis 715198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 716c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 717c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 718c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 719c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 720198cb4dfSChris Lattner 721198cb4dfSChris Lattner if (NumWarnings) 722198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 723198cb4dfSChris Lattner if (NumWarnings && NumErrors) 724198cb4dfSChris Lattner OS << " and "; 725198cb4dfSChris Lattner if (NumErrors) 726198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 727198cb4dfSChris Lattner if (NumWarnings || NumErrors) 728198cb4dfSChris Lattner OS << " generated.\n"; 729198cb4dfSChris Lattner } 7304f2bc55dSDaniel Dunbar 731aed46fcbSDaniel Dunbar if (getFrontendOpts().ShowStats && hasFileManager()) { 7324f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 7334f2bc55dSDaniel Dunbar OS << "\n"; 7344f2bc55dSDaniel Dunbar } 7354f2bc55dSDaniel Dunbar 736bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 7374f2bc55dSDaniel Dunbar } 7384f2bc55dSDaniel Dunbar 739faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 740faeb1d46SDouglas Gregor /// options. 741faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 742faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 743faeb1d46SDouglas Gregor return IK_OpenCL; 744faeb1d46SDouglas Gregor if (LangOpts.CUDA) 745faeb1d46SDouglas Gregor return IK_CUDA; 746faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 747faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 748faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 749faeb1d46SDouglas Gregor } 750faeb1d46SDouglas Gregor 75151e0b541SDouglas Gregor namespace { 752514b636aSDouglas Gregor struct CompileModuleMapData { 753514b636aSDouglas Gregor CompilerInstance &Instance; 754514b636aSDouglas Gregor GenerateModuleAction &CreateModuleAction; 755514b636aSDouglas Gregor }; 756514b636aSDouglas Gregor } 757514b636aSDouglas Gregor 758514b636aSDouglas Gregor /// \brief Helper function that executes the module-generating action under 759514b636aSDouglas Gregor /// a crash recovery context. 760514b636aSDouglas Gregor static void doCompileMapModule(void *UserData) { 761514b636aSDouglas Gregor CompileModuleMapData &Data 762514b636aSDouglas Gregor = *reinterpret_cast<CompileModuleMapData *>(UserData); 763514b636aSDouglas Gregor Data.Instance.ExecuteAction(Data.CreateModuleAction); 764514b636aSDouglas Gregor } 765514b636aSDouglas Gregor 7665dc3899cSDouglas Gregor namespace { 7675dc3899cSDouglas Gregor /// \brief Function object that checks with the given macro definition should 7685dc3899cSDouglas Gregor /// be removed, because it is one of the ignored macros. 7695dc3899cSDouglas Gregor class RemoveIgnoredMacro { 7705dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts; 7715dc3899cSDouglas Gregor 7725dc3899cSDouglas Gregor public: 7735dc3899cSDouglas Gregor explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts) 7745dc3899cSDouglas Gregor : HSOpts(HSOpts) { } 7755dc3899cSDouglas Gregor 7765dc3899cSDouglas Gregor bool operator()(const std::pair<std::string, bool> &def) const { 7772236c20fSDouglas Gregor StringRef MacroDef = def.first; 7782236c20fSDouglas Gregor return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 7795dc3899cSDouglas Gregor } 7805dc3899cSDouglas Gregor }; 7815dc3899cSDouglas Gregor } 7825dc3899cSDouglas Gregor 783514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 784514b636aSDouglas Gregor /// provided by the importing compiler instance. 785faeb1d46SDouglas Gregor static void compileModule(CompilerInstance &ImportingInstance, 786af8f0263SDouglas Gregor SourceLocation ImportLoc, 787de3ef502SDouglas Gregor Module *Module, 7886dc57927SDouglas Gregor StringRef ModuleFileName) { 789157f34bdSRafael Espindola // FIXME: have LockFileManager return an error_code so that we can 790157f34bdSRafael Espindola // avoid the mkdir when the directory already exists. 791157f34bdSRafael Espindola StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 792157f34bdSRafael Espindola llvm::sys::fs::create_directories(Dir); 793157f34bdSRafael Espindola 794e212489fSDouglas Gregor llvm::LockFileManager Locked(ModuleFileName); 79554a88810SDouglas Gregor switch (Locked) { 796e212489fSDouglas Gregor case llvm::LockFileManager::LFS_Error: 79754a88810SDouglas Gregor return; 79854a88810SDouglas Gregor 799e212489fSDouglas Gregor case llvm::LockFileManager::LFS_Owned: 80054a88810SDouglas Gregor // We're responsible for building the module ourselves. Do so below. 80154a88810SDouglas Gregor break; 80254a88810SDouglas Gregor 803e212489fSDouglas Gregor case llvm::LockFileManager::LFS_Shared: 80454a88810SDouglas Gregor // Someone else is responsible for building the module. Wait for them to 80554a88810SDouglas Gregor // finish. 80654a88810SDouglas Gregor Locked.waitForUnlock(); 807188dbef2SDouglas Gregor return; 80854a88810SDouglas Gregor } 80954a88810SDouglas Gregor 810514b636aSDouglas Gregor ModuleMap &ModMap 811514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 812514b636aSDouglas Gregor 813faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 814c95d8192SDylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> Invocation 815faeb1d46SDouglas Gregor (new CompilerInvocation(ImportingInstance.getInvocation())); 81644bf68d8SDouglas Gregor 817f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 818f545f67dSDouglas Gregor 81944bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 82044bf68d8SDouglas Gregor // reset them to their default values. 8218cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 822f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 82344bf68d8SDouglas Gregor 8245dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 8255dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 8265dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 8275dc3899cSDouglas Gregor PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 8285dc3899cSDouglas Gregor RemoveIgnoredMacro(HSOpts)), 8295dc3899cSDouglas Gregor PPOpts.Macros.end()); 8305dc3899cSDouglas Gregor 8315dc3899cSDouglas Gregor 8327d106e42SDouglas Gregor // Note the name of the module we're building. 8336dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 8347d106e42SDouglas Gregor 8357a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 8367a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 8377a626570SDouglas Gregor // instance. 8387a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 8397a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 8407a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 8417a626570SDouglas Gregor ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 8427a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 8437a626570SDouglas Gregor 844514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 845514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 846514b636aSDouglas Gregor // header. 847514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 848514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 849514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 850c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 851514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 852f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 853f545f67dSDouglas Gregor 854f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 855f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 856514b636aSDouglas Gregor 857514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 858514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 859514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 860514b636aSDouglas Gregor 861514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 862514b636aSDouglas Gregor // module. 863514b636aSDouglas Gregor CompilerInstance Instance; 864514b636aSDouglas Gregor Instance.setInvocation(&*Invocation); 8656b930967SDouglas Gregor 8666b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 8676b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 86830071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 869514b636aSDouglas Gregor 87063365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 871af8f0263SDouglas Gregor // can detect cycles in the module graph. 872af8f0263SDouglas Gregor Instance.createFileManager(); // FIXME: Adopt file manager from importer? 873af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 874af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 87563365431SDouglas Gregor SourceMgr.setModuleBuildStack( 87663365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 87763365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 878af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 879af8f0263SDouglas Gregor 8801f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 8811f76c4e8SManuel Klimek std::string InferredModuleMapContent; 8821f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 8831f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 8841f76c4e8SManuel Klimek // Use the module map where this module resides. 8851f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 8861f76c4e8SManuel Klimek FrontendInputFile(ModuleMapFile->getName(), IK)); 8871f76c4e8SManuel Klimek } else { 8881f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 8891f76c4e8SManuel Klimek Module->print(OS); 8901f76c4e8SManuel Klimek OS.flush(); 8911f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 8921f76c4e8SManuel Klimek FrontendInputFile("__inferred_module.map", IK)); 8931f76c4e8SManuel Klimek 8941f76c4e8SManuel Klimek const llvm::MemoryBuffer *ModuleMapBuffer = 8951f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 8961f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 8971f76c4e8SManuel Klimek "__inferred_module.map", InferredModuleMapContent.size(), 0); 8981f76c4e8SManuel Klimek SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer); 8991f76c4e8SManuel Klimek } 900af8f0263SDouglas Gregor 901514b636aSDouglas Gregor // Construct a module-generating action. 902963c5535SDouglas Gregor GenerateModuleAction CreateModuleAction(Module->IsSystem); 903514b636aSDouglas Gregor 904514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 905514b636aSDouglas Gregor // thread so that we get a stack large enough. 906514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 907514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 908514b636aSDouglas Gregor CompileModuleMapData Data = { Instance, CreateModuleAction }; 909514b636aSDouglas Gregor CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize); 910514b636aSDouglas Gregor 9116b930967SDouglas Gregor 912f545f67dSDouglas Gregor // Delete the temporary module map file. 913f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 914f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 915f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 91613afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 9175e306b12SDouglas Gregor 9185e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 9195e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 920c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 9215e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 9225e306b12SDouglas Gregor } 923faeb1d46SDouglas Gregor } 924faeb1d46SDouglas Gregor 92535b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 92635b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 92735b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 92835b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 92935b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 93035b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 93135b13eceSDouglas Gregor 93235b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 93335b13eceSDouglas Gregor // not have changed. 93435b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 93535b13eceSDouglas Gregor return; 93635b13eceSDouglas Gregor 93735b13eceSDouglas Gregor // If this identifier does not currently have a macro definition, 93835b13eceSDouglas Gregor // check whether it had one on the command line. 93935b13eceSDouglas Gregor if (!Id->hasMacroDefinition()) { 940b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 941b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 942b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 943b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 944b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 94535b13eceSDouglas Gregor if (FID.isInvalid()) 94635b13eceSDouglas Gregor continue; 94735b13eceSDouglas Gregor 94835b13eceSDouglas Gregor // We only care about the predefines buffer. 94905ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 95035b13eceSDouglas Gregor continue; 95135b13eceSDouglas Gregor 95235b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 95335b13eceSDouglas Gregor // Complain. 95435b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 95535b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 956b6210dffSArgyrios Kyrtzidis if (LatestDef.isUndefined()) 957b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 95835b13eceSDouglas Gregor << true; 95935b13eceSDouglas Gregor return; 96035b13eceSDouglas Gregor } 96135b13eceSDouglas Gregor 96235b13eceSDouglas Gregor // Okay: no definition in the predefines buffer. 96335b13eceSDouglas Gregor return; 96435b13eceSDouglas Gregor } 96535b13eceSDouglas Gregor 96635b13eceSDouglas Gregor // This identifier has a macro definition. Check whether we had a definition 96735b13eceSDouglas Gregor // on the command line. 968b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 969b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 970b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo PredefinedDef; 971b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 972b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 973b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 97435b13eceSDouglas Gregor if (FID.isInvalid()) 97535b13eceSDouglas Gregor continue; 97635b13eceSDouglas Gregor 97735b13eceSDouglas Gregor // We only care about the predefines buffer. 97805ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 97935b13eceSDouglas Gregor continue; 98035b13eceSDouglas Gregor 981b6210dffSArgyrios Kyrtzidis PredefinedDef = Def; 98235b13eceSDouglas Gregor break; 98335b13eceSDouglas Gregor } 98435b13eceSDouglas Gregor 98535b13eceSDouglas Gregor // If there was no definition for this macro in the predefines buffer, 98635b13eceSDouglas Gregor // complain. 987b6210dffSArgyrios Kyrtzidis if (!PredefinedDef || 988b6210dffSArgyrios Kyrtzidis (!PredefinedDef.getLocation().isValid() && 989b6210dffSArgyrios Kyrtzidis PredefinedDef.getUndefLocation().isValid())) { 99035b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 99135b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 992b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 99335b13eceSDouglas Gregor << false; 99435b13eceSDouglas Gregor return; 99535b13eceSDouglas Gregor } 99635b13eceSDouglas Gregor 99735b13eceSDouglas Gregor // If the current macro definition is the same as the predefined macro 99835b13eceSDouglas Gregor // definition, it's okay. 999b6210dffSArgyrios Kyrtzidis if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() || 10000c2f30b9SArgyrios Kyrtzidis LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP, 10010c2f30b9SArgyrios Kyrtzidis /*Syntactically=*/true)) 100235b13eceSDouglas Gregor return; 100335b13eceSDouglas Gregor 100435b13eceSDouglas Gregor // The macro definitions differ. 100535b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 100635b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 1007b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 100835b13eceSDouglas Gregor << false; 100935b13eceSDouglas Gregor } 101035b13eceSDouglas Gregor 1011527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1012527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1013527b1c95SDouglas Gregor std::string ErrorInfo; 1014527b1c95SDouglas Gregor llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo, 101516125fb6SRafael Espindola llvm::sys::fs::F_Binary); 1016527b1c95SDouglas Gregor } 1017527b1c95SDouglas Gregor 1018527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1019527b1c95SDouglas Gregor /// a long time. 1020527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1021527b1c95SDouglas Gregor struct stat StatBuf; 1022527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1023527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 1024527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1025527b1c95SDouglas Gregor 1026527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1027527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1028527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1029527b1c95SDouglas Gregor if (errno == ENOENT) { 1030527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1031527b1c95SDouglas Gregor } 1032527b1c95SDouglas Gregor return; 1033527b1c95SDouglas Gregor } 1034527b1c95SDouglas Gregor 1035527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1036527b1c95SDouglas Gregor // If not, do nothing. 1037527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 1038527b1c95SDouglas Gregor time_t CurrentTime = time(0); 1039dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1040527b1c95SDouglas Gregor return; 1041527b1c95SDouglas Gregor 1042527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1043527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1044527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1045527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1046527b1c95SDouglas Gregor 1047527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1048527b1c95SDouglas Gregor // indices. 1049527b1c95SDouglas Gregor llvm::error_code EC; 1050527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1051527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 1052527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator 1053527b1c95SDouglas Gregor Dir(ModuleCachePathNative.str(), EC), DirEnd; 1054527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1055527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1056a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1057527b1c95SDouglas Gregor continue; 1058527b1c95SDouglas Gregor 1059527b1c95SDouglas Gregor // Walk all of the files within this directory. 1060527b1c95SDouglas Gregor bool RemovedAllFiles = true; 1061527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1062527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1063527b1c95SDouglas Gregor // We only care about module and global module index files. 1064527b1c95SDouglas Gregor if (llvm::sys::path::extension(File->path()) != ".pcm" && 1065527b1c95SDouglas Gregor llvm::sys::path::filename(File->path()) != "modules.idx") { 1066527b1c95SDouglas Gregor RemovedAllFiles = false; 1067527b1c95SDouglas Gregor continue; 1068527b1c95SDouglas Gregor } 1069527b1c95SDouglas Gregor 1070527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1071527b1c95SDouglas Gregor // there. 1072527b1c95SDouglas Gregor if (::stat(File->path().c_str(), &StatBuf)) { 1073527b1c95SDouglas Gregor RemovedAllFiles = false; 1074527b1c95SDouglas Gregor continue; 1075527b1c95SDouglas Gregor } 1076527b1c95SDouglas Gregor 1077527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1078527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1079dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1080dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1081dbcf5037SBenjamin Kramer RemovedAllFiles = false; 1082527b1c95SDouglas Gregor continue; 1083527b1c95SDouglas Gregor } 1084527b1c95SDouglas Gregor 1085527b1c95SDouglas Gregor // Remove the file. 1086527b1c95SDouglas Gregor bool Existed; 1087527b1c95SDouglas Gregor if (llvm::sys::fs::remove(File->path(), Existed) || !Existed) { 1088527b1c95SDouglas Gregor RemovedAllFiles = false; 1089527b1c95SDouglas Gregor } 1090527b1c95SDouglas Gregor } 1091527b1c95SDouglas Gregor 1092527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1093527b1c95SDouglas Gregor // itself. 1094527b1c95SDouglas Gregor if (RemovedAllFiles) { 1095527b1c95SDouglas Gregor bool Existed; 1096527b1c95SDouglas Gregor llvm::sys::fs::remove(Dir->path(), Existed); 1097527b1c95SDouglas Gregor } 1098527b1c95SDouglas Gregor } 1099527b1c95SDouglas Gregor } 1100527b1c95SDouglas Gregor 11017a626570SDouglas Gregor ModuleLoadResult 11027a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1103ff2be53fSDouglas Gregor ModuleIdPath Path, 1104bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1105bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 110692304e00SRichard Smith // Determine what file we're searching from. 110792304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 110892304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 110992304e00SRichard Smith 11101805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 11111805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 11121805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 1113ff2be53fSDouglas Gregor if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { 1114ff2be53fSDouglas Gregor // Make the named module visible. 111592304e00SRichard Smith if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) 1116125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1117fb912657SDouglas Gregor ImportLoc, /*Complain=*/false); 111869021974SDouglas Gregor return LastModuleImportResult; 1119ff2be53fSDouglas Gregor } 11201805b8a4SDouglas Gregor 1121de3ef502SDouglas Gregor clang::Module *Module = 0; 11225196bc6bSDouglas Gregor 11235196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1124de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 112569021974SDouglas Gregor = KnownModules.find(Path[0].first); 11262537a364SDouglas Gregor if (Known != KnownModules.end()) { 11272537a364SDouglas Gregor // Retrieve the cached top-level module. 11282537a364SDouglas Gregor Module = Known->second; 11292537a364SDouglas Gregor } else if (ModuleName == getLangOpts().CurrentModule) { 11302537a364SDouglas Gregor // This is the module we're building. 11312537a364SDouglas Gregor Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); 11322537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 11332537a364SDouglas Gregor } else { 11345196bc6bSDouglas Gregor // Search for a module with the given name. 1135279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 11361735f4e7SDouglas Gregor std::string ModuleFileName; 11378a114ab5SDouglas Gregor if (Module) { 1138279a6c37SDouglas Gregor ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); 11398a114ab5SDouglas Gregor } else 1140279a6c37SDouglas Gregor ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); 1141faeb1d46SDouglas Gregor 114208142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 114308142534SDouglas Gregor if (!ModuleManager) { 114421931efcSDouglas Gregor if (!hasASTContext()) 114521931efcSDouglas Gregor createASTContext(); 114621931efcSDouglas Gregor 1147527b1c95SDouglas Gregor // If we're not recursively building a module, check whether we 1148527b1c95SDouglas Gregor // need to prune the module cache. 1149527b1c95SDouglas Gregor if (getSourceManager().getModuleBuildStack().empty() && 1150527b1c95SDouglas Gregor getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 1151527b1c95SDouglas Gregor getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 1152527b1c95SDouglas Gregor pruneModuleCache(getHeaderSearchOpts()); 1153527b1c95SDouglas Gregor } 1154527b1c95SDouglas Gregor 115508142534SDouglas Gregor std::string Sysroot = getHeaderSearchOpts().Sysroot; 115608142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 11578835e03cSDouglas Gregor ModuleManager = new ASTReader(getPreprocessor(), *Context, 115808142534SDouglas Gregor Sysroot.empty() ? "" : Sysroot.c_str(), 1159c1bbec85SDouglas Gregor PPOpts.DisablePCHValidation, 1160c1bbec85SDouglas Gregor /*AllowASTWithCompilerErrors=*/false, 1161c1bbec85SDouglas Gregor getFrontendOpts().UseGlobalModuleIndex); 116221931efcSDouglas Gregor if (hasASTConsumer()) { 116308142534SDouglas Gregor ModuleManager->setDeserializationListener( 116408142534SDouglas Gregor getASTConsumer().GetASTDeserializationListener()); 116508142534SDouglas Gregor getASTContext().setASTMutationListener( 116608142534SDouglas Gregor getASTConsumer().GetASTMutationListener()); 116721931efcSDouglas Gregor } 1168e2778999SDylan Noblesmith OwningPtr<ExternalASTSource> Source; 116908142534SDouglas Gregor Source.reset(ModuleManager); 117008142534SDouglas Gregor getASTContext().setExternalSource(Source); 117121931efcSDouglas Gregor if (hasSema()) 117208142534SDouglas Gregor ModuleManager->InitializeSema(getSema()); 11736137d32cSDouglas Gregor if (hasASTConsumer()) 11746137d32cSDouglas Gregor ModuleManager->StartTranslationUnit(&getASTConsumer()); 117508142534SDouglas Gregor } 117608142534SDouglas Gregor 11777029ce1aSDouglas Gregor // Try to load the module file. 11787029ce1aSDouglas Gregor unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 11797029ce1aSDouglas Gregor switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, 11807029ce1aSDouglas Gregor ImportLoc, ARRFlags)) { 118108142534SDouglas Gregor case ASTReader::Success: 118208142534SDouglas Gregor break; 118308142534SDouglas Gregor 1184963ff2c3SEli Friedman case ASTReader::OutOfDate: 11857029ce1aSDouglas Gregor case ASTReader::Missing: { 1186963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 11877029ce1aSDouglas Gregor 11887029ce1aSDouglas Gregor // If we don't have a module, we don't know how to build the module file. 11897029ce1aSDouglas Gregor // Complain and return. 11907029ce1aSDouglas Gregor if (!Module) { 11917029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 11927029ce1aSDouglas Gregor << ModuleName 11937029ce1aSDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 11947029ce1aSDouglas Gregor ModuleBuildFailed = true; 11957029ce1aSDouglas Gregor return ModuleLoadResult(); 11967029ce1aSDouglas Gregor } 11977029ce1aSDouglas Gregor 11987029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 11997029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 12007029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 12017029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 12027029ce1aSDouglas Gregor if (Pos->first == ModuleName) 12037029ce1aSDouglas Gregor break; 12047029ce1aSDouglas Gregor } 12057029ce1aSDouglas Gregor 12067029ce1aSDouglas Gregor if (Pos != PosEnd) { 12077029ce1aSDouglas Gregor SmallString<256> CyclePath; 12087029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 12097029ce1aSDouglas Gregor CyclePath += Pos->first; 12107029ce1aSDouglas Gregor CyclePath += " -> "; 12117029ce1aSDouglas Gregor } 12127029ce1aSDouglas Gregor CyclePath += ModuleName; 12137029ce1aSDouglas Gregor 12147029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 12157029ce1aSDouglas Gregor << ModuleName << CyclePath; 12167029ce1aSDouglas Gregor return ModuleLoadResult(); 12177029ce1aSDouglas Gregor } 12187a626570SDouglas Gregor 12197a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 12207a626570SDouglas Gregor // failed). 12217a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 12227a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 12237a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 12247a626570SDouglas Gregor << ModuleName 12257a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1226c1bbec85SDouglas Gregor ModuleBuildFailed = true; 12277a626570SDouglas Gregor return ModuleLoadResult(); 12287a626570SDouglas Gregor } 12297a626570SDouglas Gregor 12307029ce1aSDouglas Gregor // Try to compile the module. 1231af8f0263SDouglas Gregor compileModule(*this, ModuleNameLoc, Module, ModuleFileName); 1232188dbef2SDouglas Gregor 12337029ce1aSDouglas Gregor // Try to read the module file, now that we've compiled it. 12347029ce1aSDouglas Gregor ASTReader::ASTReadResult ReadResult 12357029ce1aSDouglas Gregor = ModuleManager->ReadAST(ModuleFileName, 12362ec29367SArgyrios Kyrtzidis serialization::MK_Module, ImportLoc, 12377029ce1aSDouglas Gregor ASTReader::ARR_Missing); 12387029ce1aSDouglas Gregor if (ReadResult != ASTReader::Success) { 12397029ce1aSDouglas Gregor if (ReadResult == ASTReader::Missing) { 12407029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, 12417029ce1aSDouglas Gregor Module? diag::err_module_not_built 12427029ce1aSDouglas Gregor : diag::err_module_not_found) 12437029ce1aSDouglas Gregor << ModuleName 12447029ce1aSDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 12457029ce1aSDouglas Gregor } 12467029ce1aSDouglas Gregor 12470f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 12487a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 1249188dbef2SDouglas Gregor KnownModules[Path[0].first] = 0; 1250c1bbec85SDouglas Gregor ModuleBuildFailed = true; 12517a626570SDouglas Gregor return ModuleLoadResult(); 1252188dbef2SDouglas Gregor } 1253188dbef2SDouglas Gregor 1254188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1255188dbef2SDouglas Gregor break; 1256188dbef2SDouglas Gregor } 1257188dbef2SDouglas Gregor 1258c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 1259c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 1260c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1261dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 126208142534SDouglas Gregor // FIXME: The ASTReader will already have complained, but can we showhorn 126308142534SDouglas Gregor // that diagnostic information into a more useful form? 126469021974SDouglas Gregor KnownModules[Path[0].first] = 0; 12657a626570SDouglas Gregor return ModuleLoadResult(); 126608142534SDouglas Gregor 126708142534SDouglas Gregor case ASTReader::Failure: 1268dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 126969021974SDouglas Gregor // Already complained, but note now that we failed. 127069021974SDouglas Gregor KnownModules[Path[0].first] = 0; 1271c1bbec85SDouglas Gregor ModuleBuildFailed = true; 12727a626570SDouglas Gregor return ModuleLoadResult(); 127308142534SDouglas Gregor } 127408142534SDouglas Gregor 127569021974SDouglas Gregor if (!Module) { 127669021974SDouglas Gregor // If we loaded the module directly, without finding a module map first, 127769021974SDouglas Gregor // we'll have loaded the module's information from the module itself. 127869021974SDouglas Gregor Module = PP->getHeaderSearchInfo().getModuleMap() 127969021974SDouglas Gregor .findModule((Path[0].first->getName())); 12805196bc6bSDouglas Gregor } 128143af5132SArgyrios Kyrtzidis 128269021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 128369021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 128469021974SDouglas Gregor } 128569021974SDouglas Gregor 128669021974SDouglas Gregor // If we never found the module, fail. 128769021974SDouglas Gregor if (!Module) 12887a626570SDouglas Gregor return ModuleLoadResult(); 128969021974SDouglas Gregor 12905196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 12915196bc6bSDouglas Gregor // a submodule. 129269021974SDouglas Gregor if (Path.size() > 1) { 12935196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 12945196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1295eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 12965196bc6bSDouglas Gregor 1297eb90e830SDouglas Gregor if (!Sub) { 12985196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1299f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 13005196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 13015196bc6bSDouglas Gregor 1302eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1303eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1304eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1305eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 13065196bc6bSDouglas Gregor /*AllowReplacements=*/true, 13075196bc6bSDouglas Gregor BestEditDistance); 13085196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1309eb90e830SDouglas Gregor if (ED < BestEditDistance) { 13105196bc6bSDouglas Gregor Best.clear(); 1311eb90e830SDouglas Gregor BestEditDistance = ED; 1312eb90e830SDouglas Gregor } 1313eb90e830SDouglas Gregor 1314eb90e830SDouglas Gregor Best.push_back((*J)->Name); 13155196bc6bSDouglas Gregor } 13165196bc6bSDouglas Gregor } 13175196bc6bSDouglas Gregor 13185196bc6bSDouglas Gregor // If there was a clear winner, user it. 13195196bc6bSDouglas Gregor if (Best.size() == 1) { 13205196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 13215196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 132269021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 13235196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 13245196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 13255196bc6bSDouglas Gregor Best[0]); 1326eb90e830SDouglas Gregor 1327eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 13285196bc6bSDouglas Gregor } 13295196bc6bSDouglas Gregor } 13305196bc6bSDouglas Gregor 1331eb90e830SDouglas Gregor if (!Sub) { 13325196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 13335196bc6bSDouglas Gregor // submodules. 13345196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 133569021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 13365196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 13375196bc6bSDouglas Gregor break; 13385196bc6bSDouglas Gregor } 13395196bc6bSDouglas Gregor 1340eb90e830SDouglas Gregor Module = Sub; 13415196bc6bSDouglas Gregor } 13425196bc6bSDouglas Gregor } 13435196bc6bSDouglas Gregor 13442537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 13452537a364SDouglas Gregor // we are parsing. 134698a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 134798a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 134898a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 134998a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 135098a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 135198a52db8SDouglas Gregor // this submodule. 135298a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 135398a52db8SDouglas Gregor // expensive (and rare). 135498a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 135598a52db8SDouglas Gregor << Module->getFullModuleName() 135698a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 135798a52db8SDouglas Gregor 13587a626570SDouglas Gregor return ModuleLoadResult(0, true); 135998a52db8SDouglas Gregor } 13601fb5c3a6SDouglas Gregor 13611fb5c3a6SDouglas Gregor // Check whether this module is available. 1362*a3feee2aSRichard Smith clang::Module::Requirement Requirement; 1363*a3feee2aSRichard Smith if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement)) { 13641fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 13651fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1366*a3feee2aSRichard Smith << Requirement.second << Requirement.first 13671fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 13681fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 13697a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 13707a626570SDouglas Gregor return ModuleLoadResult(); 13711fb5c3a6SDouglas Gregor } 13721fb5c3a6SDouglas Gregor 1373fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc, 1374fb912657SDouglas Gregor /*Complain=*/true); 137598a52db8SDouglas Gregor } 13765196bc6bSDouglas Gregor 137735b13eceSDouglas Gregor // Check for any configuration macros that have changed. 137835b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 137935b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 138035b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 138135b13eceSDouglas Gregor Module, ImportLoc); 138235b13eceSDouglas Gregor } 138335b13eceSDouglas Gregor 1384bcfc7d02SDouglas Gregor // If this module import was due to an inclusion directive, create an 1385bcfc7d02SDouglas Gregor // implicit import declaration to capture it in the AST. 1386bcfc7d02SDouglas Gregor if (IsInclusionDirective && hasASTContext()) { 1387bcfc7d02SDouglas Gregor TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 138872d1aa3cSArgyrios Kyrtzidis ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 1389bcfc7d02SDouglas Gregor ImportLoc, Module, 139072d1aa3cSArgyrios Kyrtzidis Path.back().second); 139172d1aa3cSArgyrios Kyrtzidis TU->addDecl(ImportD); 139272d1aa3cSArgyrios Kyrtzidis if (Consumer) 139372d1aa3cSArgyrios Kyrtzidis Consumer->HandleImplicitImportDecl(ImportD); 1394bcfc7d02SDouglas Gregor } 1395bcfc7d02SDouglas Gregor 13961805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 13977a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(Module, false); 13987a626570SDouglas Gregor return LastModuleImportResult; 139908142534SDouglas Gregor } 1400c147b0bcSDouglas Gregor 1401c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1402125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1403fb912657SDouglas Gregor SourceLocation ImportLoc, 1404fb912657SDouglas Gregor bool Complain){ 1405fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); 1406c147b0bcSDouglas Gregor } 1407c147b0bcSDouglas Gregor 1408