1199482Srdivacky//===--- CompilerInstance.cpp ---------------------------------------------===// 2199482Srdivacky// 3199482Srdivacky// The LLVM Compiler Infrastructure 4199482Srdivacky// 5199482Srdivacky// This file is distributed under the University of Illinois Open Source 6199482Srdivacky// License. See LICENSE.TXT for details. 7199482Srdivacky// 8199482Srdivacky//===----------------------------------------------------------------------===// 9199482Srdivacky 10199482Srdivacky#include "clang/Frontend/CompilerInstance.h" 11199482Srdivacky#include "clang/AST/ASTConsumer.h" 12199482Srdivacky#include "clang/AST/ASTContext.h" 13234353Sdim#include "clang/AST/Decl.h" 14199482Srdivacky#include "clang/Basic/Diagnostic.h" 15199482Srdivacky#include "clang/Basic/FileManager.h" 16199482Srdivacky#include "clang/Basic/SourceManager.h" 17199482Srdivacky#include "clang/Basic/TargetInfo.h" 18202379Srdivacky#include "clang/Basic/Version.h" 19226633Sdim#include "clang/Frontend/ChainedDiagnosticConsumer.h" 20202379Srdivacky#include "clang/Frontend/FrontendAction.h" 21226633Sdim#include "clang/Frontend/FrontendActions.h" 22199482Srdivacky#include "clang/Frontend/FrontendDiagnostic.h" 23221345Sdim#include "clang/Frontend/LogDiagnosticPrinter.h" 24234353Sdim#include "clang/Frontend/SerializedDiagnosticPrinter.h" 25199482Srdivacky#include "clang/Frontend/TextDiagnosticPrinter.h" 26249423Sdim#include "clang/Frontend/Utils.h" 27226633Sdim#include "clang/Frontend/VerifyDiagnosticConsumer.h" 28249423Sdim#include "clang/Lex/HeaderSearch.h" 29249423Sdim#include "clang/Lex/PTHManager.h" 30249423Sdim#include "clang/Lex/Preprocessor.h" 31249423Sdim#include "clang/Sema/CodeCompleteConsumer.h" 32249423Sdim#include "clang/Sema/Sema.h" 33212904Sdim#include "clang/Serialization/ASTReader.h" 34249423Sdim#include "llvm/ADT/Statistic.h" 35249423Sdim#include "llvm/Config/config.h" 36249423Sdim#include "llvm/Support/CrashRecoveryContext.h" 37218893Sdim#include "llvm/Support/FileSystem.h" 38218893Sdim#include "llvm/Support/Host.h" 39234353Sdim#include "llvm/Support/LockFileManager.h" 40249423Sdim#include "llvm/Support/MemoryBuffer.h" 41218893Sdim#include "llvm/Support/Path.h" 42218893Sdim#include "llvm/Support/Program.h" 43218893Sdim#include "llvm/Support/Signals.h" 44249423Sdim#include "llvm/Support/Timer.h" 45249423Sdim#include "llvm/Support/raw_ostream.h" 46218893Sdim#include "llvm/Support/system_error.h" 47249423Sdim#include <sys/stat.h> 48249423Sdim#include <time.h> 49226633Sdim 50199482Srdivackyusing namespace clang; 51199482Srdivacky 52203955SrdivackyCompilerInstance::CompilerInstance() 53249423Sdim : Invocation(new CompilerInvocation()), ModuleManager(0), 54249423Sdim BuildGlobalModuleIndex(false), ModuleBuildFailed(false) { 55203955Srdivacky} 56199482Srdivacky 57199482SrdivackyCompilerInstance::~CompilerInstance() { 58243830Sdim assert(OutputFiles.empty() && "Still output files in flight?"); 59199482Srdivacky} 60199482Srdivacky 61203955Srdivackyvoid CompilerInstance::setInvocation(CompilerInvocation *Value) { 62221345Sdim Invocation = Value; 63203955Srdivacky} 64203955Srdivacky 65249423Sdimbool CompilerInstance::shouldBuildGlobalModuleIndex() const { 66249423Sdim return (BuildGlobalModuleIndex || 67249423Sdim (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 68249423Sdim getFrontendOpts().GenerateGlobalModuleIndex)) && 69249423Sdim !ModuleBuildFailed; 70249423Sdim} 71249423Sdim 72226633Sdimvoid CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 73206275Srdivacky Diagnostics = Value; 74199482Srdivacky} 75199482Srdivacky 76199482Srdivackyvoid CompilerInstance::setTarget(TargetInfo *Value) { 77221345Sdim Target = Value; 78199482Srdivacky} 79199482Srdivacky 80199482Srdivackyvoid CompilerInstance::setFileManager(FileManager *Value) { 81221345Sdim FileMgr = Value; 82199482Srdivacky} 83199482Srdivacky 84226633Sdimvoid CompilerInstance::setSourceManager(SourceManager *Value) { 85221345Sdim SourceMgr = Value; 86199482Srdivacky} 87199482Srdivacky 88221345Sdimvoid CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 89199482Srdivacky 90221345Sdimvoid CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; } 91199482Srdivacky 92212904Sdimvoid CompilerInstance::setSema(Sema *S) { 93212904Sdim TheSema.reset(S); 94212904Sdim} 95212904Sdim 96199482Srdivackyvoid CompilerInstance::setASTConsumer(ASTConsumer *Value) { 97199482Srdivacky Consumer.reset(Value); 98199482Srdivacky} 99199482Srdivacky 100199482Srdivackyvoid CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 101199482Srdivacky CompletionConsumer.reset(Value); 102199482Srdivacky} 103199482Srdivacky 104199482Srdivacky// Diagnostics 105243830Sdimstatic void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 106221345Sdim const CodeGenOptions *CodeGenOpts, 107226633Sdim DiagnosticsEngine &Diags) { 108221345Sdim std::string ErrorInfo; 109221345Sdim bool OwnsStream = false; 110226633Sdim raw_ostream *OS = &llvm::errs(); 111243830Sdim if (DiagOpts->DiagnosticLogFile != "-") { 112221345Sdim // Create the output stream. 113221345Sdim llvm::raw_fd_ostream *FileOS( 114243830Sdim new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), 115221345Sdim ErrorInfo, llvm::raw_fd_ostream::F_Append)); 116221345Sdim if (!ErrorInfo.empty()) { 117221345Sdim Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 118249423Sdim << DiagOpts->DiagnosticLogFile << ErrorInfo; 119221345Sdim } else { 120221345Sdim FileOS->SetUnbuffered(); 121221345Sdim FileOS->SetUseAtomicWrites(true); 122221345Sdim OS = FileOS; 123221345Sdim OwnsStream = true; 124221345Sdim } 125221345Sdim } 126221345Sdim 127221345Sdim // Chain in the diagnostic client which will log the diagnostics. 128221345Sdim LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, 129221345Sdim OwnsStream); 130221345Sdim if (CodeGenOpts) 131221345Sdim Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 132226633Sdim Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); 133221345Sdim} 134221345Sdim 135243830Sdimstatic void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 136234353Sdim DiagnosticsEngine &Diags, 137234353Sdim StringRef OutputFile) { 138234353Sdim std::string ErrorInfo; 139234353Sdim OwningPtr<llvm::raw_fd_ostream> OS; 140234353Sdim OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, 141234353Sdim llvm::raw_fd_ostream::F_Binary)); 142234353Sdim 143234353Sdim if (!ErrorInfo.empty()) { 144234353Sdim Diags.Report(diag::warn_fe_serialized_diag_failure) 145234353Sdim << OutputFile << ErrorInfo; 146234353Sdim return; 147234353Sdim } 148234353Sdim 149234353Sdim DiagnosticConsumer *SerializedConsumer = 150234353Sdim clang::serialized_diags::create(OS.take(), DiagOpts); 151234353Sdim 152234353Sdim 153234353Sdim Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), 154234353Sdim SerializedConsumer)); 155234353Sdim} 156234353Sdim 157249423Sdimvoid CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 158251662Sdim bool ShouldOwnClient) { 159249423Sdim Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 160251662Sdim ShouldOwnClient, &getCodeGenOpts()); 161199482Srdivacky} 162199482Srdivacky 163234353SdimIntrusiveRefCntPtr<DiagnosticsEngine> 164243830SdimCompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 165226633Sdim DiagnosticConsumer *Client, 166226633Sdim bool ShouldOwnClient, 167221345Sdim const CodeGenOptions *CodeGenOpts) { 168234353Sdim IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 169234353Sdim IntrusiveRefCntPtr<DiagnosticsEngine> 170243830Sdim Diags(new DiagnosticsEngine(DiagID, Opts)); 171199482Srdivacky 172199482Srdivacky // Create the diagnostic client for reporting errors or for 173199482Srdivacky // implementing -verify. 174226633Sdim if (Client) { 175251662Sdim Diags->setClient(Client, ShouldOwnClient); 176226633Sdim } else 177212904Sdim Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 178199482Srdivacky 179199482Srdivacky // Chain in -verify checker, if requested. 180243830Sdim if (Opts->VerifyDiagnostics) 181226633Sdim Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 182199482Srdivacky 183221345Sdim // Chain in -diagnostic-log-file dumper, if requested. 184243830Sdim if (!Opts->DiagnosticLogFile.empty()) 185221345Sdim SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 186226633Sdim 187243830Sdim if (!Opts->DiagnosticSerializationFile.empty()) 188234353Sdim SetupSerializedDiagnostics(Opts, *Diags, 189243830Sdim Opts->DiagnosticSerializationFile); 190234353Sdim 191199482Srdivacky // Configure our handling of diagnostics. 192243830Sdim ProcessWarningOptions(*Diags, *Opts); 193199482Srdivacky 194206275Srdivacky return Diags; 195199482Srdivacky} 196199482Srdivacky 197199482Srdivacky// File Manager 198199482Srdivacky 199199482Srdivackyvoid CompilerInstance::createFileManager() { 200221345Sdim FileMgr = new FileManager(getFileSystemOpts()); 201199482Srdivacky} 202199482Srdivacky 203199482Srdivacky// Source Manager 204199482Srdivacky 205218893Sdimvoid CompilerInstance::createSourceManager(FileManager &FileMgr) { 206221345Sdim SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 207199482Srdivacky} 208199482Srdivacky 209199482Srdivacky// Preprocessor 210199482Srdivacky 211199482Srdivackyvoid CompilerInstance::createPreprocessor() { 212226633Sdim const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 213199482Srdivacky 214199482Srdivacky // Create a PTH manager if we are using some form of a token cache. 215199482Srdivacky PTHManager *PTHMgr = 0; 216199482Srdivacky if (!PPOpts.TokenCache.empty()) 217226633Sdim PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 218199482Srdivacky 219199482Srdivacky // Create the Preprocessor. 220243830Sdim HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 221243830Sdim getFileManager(), 222234353Sdim getDiagnostics(), 223234353Sdim getLangOpts(), 224234353Sdim &getTarget()); 225243830Sdim PP = new Preprocessor(&getPreprocessorOpts(), 226243830Sdim getDiagnostics(), getLangOpts(), &getTarget(), 227226633Sdim getSourceManager(), *HeaderInfo, *this, PTHMgr, 228226633Sdim /*OwnsHeaderSearch=*/true); 229199482Srdivacky 230199482Srdivacky // Note that this is different then passing PTHMgr to Preprocessor's ctor. 231199482Srdivacky // That argument is used as the IdentifierInfoLookup argument to 232199482Srdivacky // IdentifierTable's ctor. 233199482Srdivacky if (PTHMgr) { 234226633Sdim PTHMgr->setPreprocessor(&*PP); 235199482Srdivacky PP->setPTHManager(PTHMgr); 236199482Srdivacky } 237199482Srdivacky 238205408Srdivacky if (PPOpts.DetailedRecord) 239249423Sdim PP->createPreprocessingRecord(); 240199482Srdivacky 241226633Sdim InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); 242226633Sdim 243249423Sdim PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 244249423Sdim 245226633Sdim // Set up the module path, including the hash for the 246226633Sdim // module-creation options. 247234353Sdim SmallString<256> SpecificModuleCache( 248226633Sdim getHeaderSearchOpts().ModuleCachePath); 249226633Sdim if (!getHeaderSearchOpts().DisableModuleHash) 250226633Sdim llvm::sys::path::append(SpecificModuleCache, 251226633Sdim getInvocation().getModuleHash()); 252234353Sdim PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache); 253226633Sdim 254199482Srdivacky // Handle generating dependencies, if requested. 255226633Sdim const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 256199482Srdivacky if (!DepOpts.OutputFile.empty()) 257199482Srdivacky AttachDependencyFileGen(*PP, DepOpts); 258234353Sdim if (!DepOpts.DOTOutputFile.empty()) 259234353Sdim AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 260234353Sdim getHeaderSearchOpts().Sysroot); 261199482Srdivacky 262234353Sdim 263218893Sdim // Handle generating header include information, if requested. 264218893Sdim if (DepOpts.ShowHeaderIncludes) 265218893Sdim AttachHeaderIncludeGen(*PP); 266218893Sdim if (!DepOpts.HeaderIncludeOutputFile.empty()) { 267226633Sdim StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 268218893Sdim if (OutputPath == "-") 269218893Sdim OutputPath = ""; 270221345Sdim AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, 271221345Sdim /*ShowDepth=*/false); 272218893Sdim } 273199482Srdivacky} 274199482Srdivacky 275199482Srdivacky// ASTContext 276199482Srdivacky 277199482Srdivackyvoid CompilerInstance::createASTContext() { 278199482Srdivacky Preprocessor &PP = getPreprocessor(); 279221345Sdim Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 280226633Sdim &getTarget(), PP.getIdentifierTable(), 281221345Sdim PP.getSelectorTable(), PP.getBuiltinInfo(), 282221345Sdim /*size_reserve=*/ 0); 283199482Srdivacky} 284199482Srdivacky 285199482Srdivacky// ExternalASTSource 286199482Srdivacky 287226633Sdimvoid CompilerInstance::createPCHExternalASTSource(StringRef Path, 288212904Sdim bool DisablePCHValidation, 289234353Sdim bool AllowPCHWithCompilerErrors, 290212904Sdim void *DeserializationListener){ 291234353Sdim OwningPtr<ExternalASTSource> Source; 292218893Sdim bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 293199482Srdivacky Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, 294226633Sdim DisablePCHValidation, 295234353Sdim AllowPCHWithCompilerErrors, 296212904Sdim getPreprocessor(), getASTContext(), 297218893Sdim DeserializationListener, 298249423Sdim Preamble, 299249423Sdim getFrontendOpts().UseGlobalModuleIndex)); 300226633Sdim ModuleManager = static_cast<ASTReader*>(Source.get()); 301199482Srdivacky getASTContext().setExternalSource(Source); 302199482Srdivacky} 303199482Srdivacky 304199482SrdivackyExternalASTSource * 305226633SdimCompilerInstance::createPCHExternalASTSource(StringRef Path, 306199482Srdivacky const std::string &Sysroot, 307212904Sdim bool DisablePCHValidation, 308234353Sdim bool AllowPCHWithCompilerErrors, 309199482Srdivacky Preprocessor &PP, 310212904Sdim ASTContext &Context, 311218893Sdim void *DeserializationListener, 312249423Sdim bool Preamble, 313249423Sdim bool UseGlobalModuleIndex) { 314234353Sdim OwningPtr<ASTReader> Reader; 315226633Sdim Reader.reset(new ASTReader(PP, Context, 316226633Sdim Sysroot.empty() ? "" : Sysroot.c_str(), 317243830Sdim DisablePCHValidation, 318249423Sdim AllowPCHWithCompilerErrors, 319249423Sdim UseGlobalModuleIndex)); 320199482Srdivacky 321212904Sdim Reader->setDeserializationListener( 322212904Sdim static_cast<ASTDeserializationListener *>(DeserializationListener)); 323218893Sdim switch (Reader->ReadAST(Path, 324226633Sdim Preamble ? serialization::MK_Preamble 325243830Sdim : serialization::MK_PCH, 326249423Sdim SourceLocation(), 327243830Sdim ASTReader::ARR_None)) { 328212904Sdim case ASTReader::Success: 329199482Srdivacky // Set the predefines buffer as suggested by the PCH reader. Typically, the 330199482Srdivacky // predefines buffer will be empty. 331199482Srdivacky PP.setPredefines(Reader->getSuggestedPredefines()); 332199482Srdivacky return Reader.take(); 333199482Srdivacky 334212904Sdim case ASTReader::Failure: 335199482Srdivacky // Unrecoverable failure: don't even try to process the input file. 336199482Srdivacky break; 337199482Srdivacky 338249423Sdim case ASTReader::Missing: 339243830Sdim case ASTReader::OutOfDate: 340243830Sdim case ASTReader::VersionMismatch: 341243830Sdim case ASTReader::ConfigurationMismatch: 342243830Sdim case ASTReader::HadErrors: 343199482Srdivacky // No suitable PCH file could be found. Return an error. 344199482Srdivacky break; 345199482Srdivacky } 346199482Srdivacky 347199482Srdivacky return 0; 348199482Srdivacky} 349199482Srdivacky 350199482Srdivacky// Code Completion 351199482Srdivacky 352226633Sdimstatic bool EnableCodeCompletion(Preprocessor &PP, 353212904Sdim const std::string &Filename, 354212904Sdim unsigned Line, 355212904Sdim unsigned Column) { 356212904Sdim // Tell the source manager to chop off the given file at a specific 357212904Sdim // line and column. 358212904Sdim const FileEntry *Entry = PP.getFileManager().getFile(Filename); 359212904Sdim if (!Entry) { 360212904Sdim PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 361212904Sdim << Filename; 362212904Sdim return true; 363212904Sdim } 364212904Sdim 365212904Sdim // Truncate the named file at the given line/column. 366212904Sdim PP.SetCodeCompletionPoint(Entry, Line, Column); 367212904Sdim return false; 368212904Sdim} 369212904Sdim 370199482Srdivackyvoid CompilerInstance::createCodeCompletionConsumer() { 371199482Srdivacky const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 372212904Sdim if (!CompletionConsumer) { 373234353Sdim setCodeCompletionConsumer( 374212904Sdim createCodeCompletionConsumer(getPreprocessor(), 375212904Sdim Loc.FileName, Loc.Line, Loc.Column, 376239462Sdim getFrontendOpts().CodeCompleteOpts, 377212904Sdim llvm::outs())); 378212904Sdim if (!CompletionConsumer) 379212904Sdim return; 380212904Sdim } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 381212904Sdim Loc.Line, Loc.Column)) { 382234353Sdim setCodeCompletionConsumer(0); 383205219Srdivacky return; 384212904Sdim } 385199990Srdivacky 386199990Srdivacky if (CompletionConsumer->isOutputBinary() && 387199990Srdivacky llvm::sys::Program::ChangeStdoutToBinary()) { 388199990Srdivacky getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 389234353Sdim setCodeCompletionConsumer(0); 390199990Srdivacky } 391199482Srdivacky} 392199482Srdivacky 393199990Srdivackyvoid CompilerInstance::createFrontendTimer() { 394199990Srdivacky FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); 395199990Srdivacky} 396199990Srdivacky 397199482SrdivackyCodeCompleteConsumer * 398199482SrdivackyCompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 399199482Srdivacky const std::string &Filename, 400199482Srdivacky unsigned Line, 401199482Srdivacky unsigned Column, 402239462Sdim const CodeCompleteOptions &Opts, 403226633Sdim raw_ostream &OS) { 404212904Sdim if (EnableCodeCompletion(PP, Filename, Line, Column)) 405199482Srdivacky return 0; 406199482Srdivacky 407199482Srdivacky // Set up the creation routine for code-completion. 408239462Sdim return new PrintingCodeCompleteConsumer(Opts, OS); 409199482Srdivacky} 410199482Srdivacky 411226633Sdimvoid CompilerInstance::createSema(TranslationUnitKind TUKind, 412212904Sdim CodeCompleteConsumer *CompletionConsumer) { 413212904Sdim TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 414226633Sdim TUKind, CompletionConsumer)); 415212904Sdim} 416212904Sdim 417199482Srdivacky// Output Files 418199482Srdivacky 419218893Sdimvoid CompilerInstance::addOutputFile(const OutputFile &OutFile) { 420218893Sdim assert(OutFile.OS && "Attempt to add empty stream to output list!"); 421218893Sdim OutputFiles.push_back(OutFile); 422199482Srdivacky} 423199482Srdivacky 424204962Srdivackyvoid CompilerInstance::clearOutputFiles(bool EraseFiles) { 425218893Sdim for (std::list<OutputFile>::iterator 426199482Srdivacky it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) { 427218893Sdim delete it->OS; 428218893Sdim if (!it->TempFilename.empty()) { 429221345Sdim if (EraseFiles) { 430221345Sdim bool existed; 431221345Sdim llvm::sys::fs::remove(it->TempFilename, existed); 432221345Sdim } else { 433234353Sdim SmallString<128> NewOutFile(it->Filename); 434221345Sdim 435218893Sdim // If '-working-directory' was passed, the output filename should be 436218893Sdim // relative to that. 437221345Sdim FileMgr->FixupRelativePath(NewOutFile); 438221345Sdim if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename, 439221345Sdim NewOutFile.str())) { 440239462Sdim getDiagnostics().Report(diag::err_unable_to_rename_temp) 441221345Sdim << it->TempFilename << it->Filename << ec.message(); 442221345Sdim 443221345Sdim bool existed; 444221345Sdim llvm::sys::fs::remove(it->TempFilename, existed); 445218893Sdim } 446218893Sdim } 447218893Sdim } else if (!it->Filename.empty() && EraseFiles) 448218893Sdim llvm::sys::Path(it->Filename).eraseFromDisk(); 449226633Sdim 450199482Srdivacky } 451199482Srdivacky OutputFiles.clear(); 452199482Srdivacky} 453199482Srdivacky 454199482Srdivackyllvm::raw_fd_ostream * 455199482SrdivackyCompilerInstance::createDefaultOutputFile(bool Binary, 456226633Sdim StringRef InFile, 457226633Sdim StringRef Extension) { 458199482Srdivacky return createOutputFile(getFrontendOpts().OutputFile, Binary, 459234353Sdim /*RemoveFileOnSignal=*/true, InFile, Extension, 460234353Sdim /*UseTemporary=*/true); 461199482Srdivacky} 462199482Srdivacky 463199482Srdivackyllvm::raw_fd_ostream * 464226633SdimCompilerInstance::createOutputFile(StringRef OutputPath, 465218893Sdim bool Binary, bool RemoveFileOnSignal, 466226633Sdim StringRef InFile, 467226633Sdim StringRef Extension, 468234353Sdim bool UseTemporary, 469234353Sdim bool CreateMissingDirectories) { 470218893Sdim std::string Error, OutputPathName, TempPathName; 471199482Srdivacky llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary, 472218893Sdim RemoveFileOnSignal, 473199482Srdivacky InFile, Extension, 474226633Sdim UseTemporary, 475234353Sdim CreateMissingDirectories, 476218893Sdim &OutputPathName, 477218893Sdim &TempPathName); 478199482Srdivacky if (!OS) { 479200583Srdivacky getDiagnostics().Report(diag::err_fe_unable_to_open_output) 480200583Srdivacky << OutputPath << Error; 481200583Srdivacky return 0; 482199482Srdivacky } 483199482Srdivacky 484199482Srdivacky // Add the output file -- but don't try to remove "-", since this means we are 485199482Srdivacky // using stdin. 486218893Sdim addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 487218893Sdim TempPathName, OS)); 488199482Srdivacky 489199482Srdivacky return OS; 490199482Srdivacky} 491199482Srdivacky 492199482Srdivackyllvm::raw_fd_ostream * 493226633SdimCompilerInstance::createOutputFile(StringRef OutputPath, 494199482Srdivacky std::string &Error, 495199482Srdivacky bool Binary, 496218893Sdim bool RemoveFileOnSignal, 497226633Sdim StringRef InFile, 498226633Sdim StringRef Extension, 499226633Sdim bool UseTemporary, 500234353Sdim bool CreateMissingDirectories, 501218893Sdim std::string *ResultPathName, 502218893Sdim std::string *TempPathName) { 503234353Sdim assert((!CreateMissingDirectories || UseTemporary) && 504234353Sdim "CreateMissingDirectories is only allowed when using temporary files"); 505234353Sdim 506218893Sdim std::string OutFile, TempFile; 507199482Srdivacky if (!OutputPath.empty()) { 508199482Srdivacky OutFile = OutputPath; 509199482Srdivacky } else if (InFile == "-") { 510199482Srdivacky OutFile = "-"; 511199482Srdivacky } else if (!Extension.empty()) { 512199482Srdivacky llvm::sys::Path Path(InFile); 513199482Srdivacky Path.eraseSuffix(); 514199482Srdivacky Path.appendSuffix(Extension); 515199482Srdivacky OutFile = Path.str(); 516199482Srdivacky } else { 517199482Srdivacky OutFile = "-"; 518199482Srdivacky } 519226633Sdim 520234353Sdim OwningPtr<llvm::raw_fd_ostream> OS; 521226633Sdim std::string OSFile; 522226633Sdim 523226633Sdim if (UseTemporary && OutFile != "-") { 524234353Sdim // Only create the temporary if the parent directory exists (or create 525234353Sdim // missing directories is true) and we can actually write to OutPath, 526234353Sdim // otherwise we want to fail early. 527234353Sdim SmallString<256> AbsPath(OutputPath); 528234353Sdim llvm::sys::fs::make_absolute(AbsPath); 529234353Sdim llvm::sys::Path OutPath(AbsPath); 530234353Sdim bool ParentExists = false; 531234353Sdim if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()), 532234353Sdim ParentExists)) 533234353Sdim ParentExists = false; 534218893Sdim bool Exists; 535234353Sdim if ((CreateMissingDirectories || ParentExists) && 536234353Sdim ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) || 537234353Sdim (OutPath.isRegularFile() && OutPath.canWrite()))) { 538218893Sdim // Create a temporary file. 539234353Sdim SmallString<128> TempPath; 540226633Sdim TempPath = OutFile; 541226633Sdim TempPath += "-%%%%%%%%"; 542226633Sdim int fd; 543226633Sdim if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, 544236260Sdim /*makeAbsolute=*/false, 0664) 545236260Sdim == llvm::errc::success) { 546226633Sdim OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 547226633Sdim OSFile = TempFile = TempPath.str(); 548226633Sdim } 549218893Sdim } 550218893Sdim } 551199482Srdivacky 552226633Sdim if (!OS) { 553226633Sdim OSFile = OutFile; 554226633Sdim OS.reset( 555226633Sdim new llvm::raw_fd_ostream(OSFile.c_str(), Error, 556226633Sdim (Binary ? llvm::raw_fd_ostream::F_Binary : 0))); 557226633Sdim if (!Error.empty()) 558226633Sdim return 0; 559226633Sdim } 560218893Sdim 561218893Sdim // Make sure the out stream file gets removed if we crash. 562218893Sdim if (RemoveFileOnSignal) 563218893Sdim llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile)); 564218893Sdim 565199482Srdivacky if (ResultPathName) 566199482Srdivacky *ResultPathName = OutFile; 567218893Sdim if (TempPathName) 568218893Sdim *TempPathName = TempFile; 569199482Srdivacky 570199990Srdivacky return OS.take(); 571199482Srdivacky} 572199482Srdivacky 573199482Srdivacky// Initialization Utilities 574199482Srdivacky 575243830Sdimbool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 576243830Sdim return InitializeSourceManager(Input, getDiagnostics(), 577234353Sdim getFileManager(), getSourceManager(), 578234353Sdim getFrontendOpts()); 579199482Srdivacky} 580199482Srdivacky 581243830Sdimbool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 582226633Sdim DiagnosticsEngine &Diags, 583199482Srdivacky FileManager &FileMgr, 584199482Srdivacky SourceManager &SourceMgr, 585199482Srdivacky const FrontendOptions &Opts) { 586243830Sdim SrcMgr::CharacteristicKind 587243830Sdim Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 588243830Sdim 589243830Sdim if (Input.isBuffer()) { 590243830Sdim SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind); 591243830Sdim assert(!SourceMgr.getMainFileID().isInvalid() && 592243830Sdim "Couldn't establish MainFileID!"); 593243830Sdim return true; 594243830Sdim } 595243830Sdim 596243830Sdim StringRef InputFile = Input.getFile(); 597243830Sdim 598226633Sdim // Figure out where to get and map in the main file. 599226633Sdim if (InputFile != "-") { 600199482Srdivacky const FileEntry *File = FileMgr.getFile(InputFile); 601218893Sdim if (!File) { 602199482Srdivacky Diags.Report(diag::err_fe_error_reading) << InputFile; 603199482Srdivacky return false; 604199482Srdivacky } 605243830Sdim 606243830Sdim // The natural SourceManager infrastructure can't currently handle named 607243830Sdim // pipes, but we would at least like to accept them for the main 608243830Sdim // file. Detect them here, read them with the more generic MemoryBuffer 609243830Sdim // function, and simply override their contents as we do for STDIN. 610243830Sdim if (File->isNamedPipe()) { 611243830Sdim OwningPtr<llvm::MemoryBuffer> MB; 612243830Sdim if (llvm::error_code ec = llvm::MemoryBuffer::getFile(InputFile, MB)) { 613243830Sdim Diags.Report(diag::err_cannot_open_file) << InputFile << ec.message(); 614243830Sdim return false; 615243830Sdim } 616249423Sdim 617249423Sdim // Create a new virtual file that will have the correct size. 618249423Sdim File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); 619243830Sdim SourceMgr.overrideFileContents(File, MB.take()); 620243830Sdim } 621249423Sdim 622249423Sdim SourceMgr.createMainFileID(File, Kind); 623199482Srdivacky } else { 624234353Sdim OwningPtr<llvm::MemoryBuffer> SB; 625218893Sdim if (llvm::MemoryBuffer::getSTDIN(SB)) { 626218893Sdim // FIXME: Give ec.message() in this diag. 627199482Srdivacky Diags.Report(diag::err_fe_error_reading_stdin); 628199482Srdivacky return false; 629199482Srdivacky } 630218893Sdim const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 631218893Sdim SB->getBufferSize(), 0); 632234353Sdim SourceMgr.createMainFileID(File, Kind); 633218893Sdim SourceMgr.overrideFileContents(File, SB.take()); 634199482Srdivacky } 635199482Srdivacky 636218893Sdim assert(!SourceMgr.getMainFileID().isInvalid() && 637218893Sdim "Couldn't establish MainFileID!"); 638199482Srdivacky return true; 639199482Srdivacky} 640202379Srdivacky 641202379Srdivacky// High-Level Operations 642202379Srdivacky 643202379Srdivackybool CompilerInstance::ExecuteAction(FrontendAction &Act) { 644202379Srdivacky assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 645202379Srdivacky assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 646202379Srdivacky assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 647202379Srdivacky 648202379Srdivacky // FIXME: Take this as an argument, once all the APIs we used have moved to 649202379Srdivacky // taking it as an input instead of hard-coding llvm::errs. 650226633Sdim raw_ostream &OS = llvm::errs(); 651202379Srdivacky 652202379Srdivacky // Create the target instance. 653249423Sdim setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts())); 654202379Srdivacky if (!hasTarget()) 655202379Srdivacky return false; 656202379Srdivacky 657202379Srdivacky // Inform the target of the language options. 658202379Srdivacky // 659202379Srdivacky // FIXME: We shouldn't need to do this, the target should be immutable once 660202379Srdivacky // created. This complexity should be lifted elsewhere. 661202379Srdivacky getTarget().setForcedLangOptions(getLangOpts()); 662202379Srdivacky 663234982Sdim // rewriter project will change target built-in bool type from its default. 664234982Sdim if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 665234982Sdim getTarget().noSignedCharForObjCBool(); 666234982Sdim 667202379Srdivacky // Validate/process some options. 668202379Srdivacky if (getHeaderSearchOpts().Verbose) 669202379Srdivacky OS << "clang -cc1 version " CLANG_VERSION_STRING 670202379Srdivacky << " based upon " << PACKAGE_STRING 671234353Sdim << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 672202379Srdivacky 673202379Srdivacky if (getFrontendOpts().ShowTimers) 674202379Srdivacky createFrontendTimer(); 675202379Srdivacky 676206084Srdivacky if (getFrontendOpts().ShowStats) 677206084Srdivacky llvm::EnableStatistics(); 678226633Sdim 679202379Srdivacky for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 680210299Sed // Reset the ID tables if we are reusing the SourceManager. 681210299Sed if (hasSourceManager()) 682210299Sed getSourceManager().clearIDTables(); 683202379Srdivacky 684234353Sdim if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 685202379Srdivacky Act.Execute(); 686202379Srdivacky Act.EndSourceFile(); 687202379Srdivacky } 688202379Srdivacky } 689202379Srdivacky 690234353Sdim // Notify the diagnostic client that all files were processed. 691234353Sdim getDiagnostics().getClient()->finish(); 692234353Sdim 693207619Srdivacky if (getDiagnosticOpts().ShowCarets) { 694218893Sdim // We can have multiple diagnostics sharing one diagnostic client. 695218893Sdim // Get the total number of warnings/errors from the client. 696218893Sdim unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 697218893Sdim unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 698226633Sdim 699207619Srdivacky if (NumWarnings) 700207619Srdivacky OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 701207619Srdivacky if (NumWarnings && NumErrors) 702207619Srdivacky OS << " and "; 703207619Srdivacky if (NumErrors) 704207619Srdivacky OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 705207619Srdivacky if (NumWarnings || NumErrors) 706207619Srdivacky OS << " generated.\n"; 707207619Srdivacky } 708202379Srdivacky 709210299Sed if (getFrontendOpts().ShowStats && hasFileManager()) { 710202379Srdivacky getFileManager().PrintStats(); 711202379Srdivacky OS << "\n"; 712202379Srdivacky } 713202379Srdivacky 714218893Sdim return !getDiagnostics().getClient()->getNumErrors(); 715202379Srdivacky} 716202379Srdivacky 717226633Sdim/// \brief Determine the appropriate source input kind based on language 718226633Sdim/// options. 719226633Sdimstatic InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 720226633Sdim if (LangOpts.OpenCL) 721226633Sdim return IK_OpenCL; 722226633Sdim if (LangOpts.CUDA) 723226633Sdim return IK_CUDA; 724226633Sdim if (LangOpts.ObjC1) 725226633Sdim return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 726226633Sdim return LangOpts.CPlusPlus? IK_CXX : IK_C; 727226633Sdim} 728202379Srdivacky 729226633Sdimnamespace { 730234353Sdim struct CompileModuleMapData { 731226633Sdim CompilerInstance &Instance; 732234353Sdim GenerateModuleAction &CreateModuleAction; 733226633Sdim }; 734226633Sdim} 735226633Sdim 736226633Sdim/// \brief Helper function that executes the module-generating action under 737226633Sdim/// a crash recovery context. 738234353Sdimstatic void doCompileMapModule(void *UserData) { 739234353Sdim CompileModuleMapData &Data 740234353Sdim = *reinterpret_cast<CompileModuleMapData *>(UserData); 741226633Sdim Data.Instance.ExecuteAction(Data.CreateModuleAction); 742226633Sdim} 743226633Sdim 744249423Sdimnamespace { 745249423Sdim /// \brief Function object that checks with the given macro definition should 746249423Sdim /// be removed, because it is one of the ignored macros. 747249423Sdim class RemoveIgnoredMacro { 748249423Sdim const HeaderSearchOptions &HSOpts; 749249423Sdim 750249423Sdim public: 751249423Sdim explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts) 752249423Sdim : HSOpts(HSOpts) { } 753249423Sdim 754249423Sdim bool operator()(const std::pair<std::string, bool> &def) const { 755249423Sdim StringRef MacroDef = def.first; 756249423Sdim return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 757249423Sdim } 758249423Sdim }; 759249423Sdim} 760249423Sdim 761234353Sdim/// \brief Compile a module file for the given module, using the options 762234353Sdim/// provided by the importing compiler instance. 763226633Sdimstatic void compileModule(CompilerInstance &ImportingInstance, 764249423Sdim SourceLocation ImportLoc, 765234353Sdim Module *Module, 766234353Sdim StringRef ModuleFileName) { 767234353Sdim llvm::LockFileManager Locked(ModuleFileName); 768226633Sdim switch (Locked) { 769234353Sdim case llvm::LockFileManager::LFS_Error: 770226633Sdim return; 771226633Sdim 772234353Sdim case llvm::LockFileManager::LFS_Owned: 773226633Sdim // We're responsible for building the module ourselves. Do so below. 774226633Sdim break; 775226633Sdim 776234353Sdim case llvm::LockFileManager::LFS_Shared: 777226633Sdim // Someone else is responsible for building the module. Wait for them to 778226633Sdim // finish. 779226633Sdim Locked.waitForUnlock(); 780243830Sdim return; 781226633Sdim } 782226633Sdim 783234353Sdim ModuleMap &ModMap 784234353Sdim = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 785234353Sdim 786226633Sdim // Construct a compiler invocation for creating this module. 787234353Sdim IntrusiveRefCntPtr<CompilerInvocation> Invocation 788226633Sdim (new CompilerInvocation(ImportingInstance.getInvocation())); 789226633Sdim 790234353Sdim PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 791234353Sdim 792226633Sdim // For any options that aren't intended to affect how a module is built, 793226633Sdim // reset them to their default values. 794234353Sdim Invocation->getLangOpts()->resetNonModularOptions(); 795234353Sdim PPOpts.resetNonModularOptions(); 796226633Sdim 797249423Sdim // Remove any macro definitions that are explicitly ignored by the module. 798249423Sdim // They aren't supposed to affect how the module is built anyway. 799249423Sdim const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 800249423Sdim PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 801249423Sdim RemoveIgnoredMacro(HSOpts)), 802249423Sdim PPOpts.Macros.end()); 803249423Sdim 804249423Sdim 805234353Sdim // Note the name of the module we're building. 806234353Sdim Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 807234353Sdim 808249423Sdim // Make sure that the failed-module structure has been allocated in 809249423Sdim // the importing instance, and propagate the pointer to the newly-created 810249423Sdim // instance. 811249423Sdim PreprocessorOptions &ImportingPPOpts 812249423Sdim = ImportingInstance.getInvocation().getPreprocessorOpts(); 813249423Sdim if (!ImportingPPOpts.FailedModules) 814249423Sdim ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 815249423Sdim PPOpts.FailedModules = ImportingPPOpts.FailedModules; 816226633Sdim 817234353Sdim // If there is a module map file, build the module using the module map. 818226633Sdim // Set up the inputs/outputs so that we build the module from its umbrella 819226633Sdim // header. 820226633Sdim FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 821226633Sdim FrontendOpts.OutputFile = ModuleFileName.str(); 822226633Sdim FrontendOpts.DisableFree = false; 823249423Sdim FrontendOpts.GenerateGlobalModuleIndex = false; 824226633Sdim FrontendOpts.Inputs.clear(); 825234353Sdim InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 826226633Sdim 827234353Sdim // Get or create the module map that we'll use to build this module. 828234353Sdim SmallString<128> TempModuleMapFileName; 829234353Sdim if (const FileEntry *ModuleMapFile 830234353Sdim = ModMap.getContainingModuleMapFile(Module)) { 831234353Sdim // Use the module map where this module resides. 832234353Sdim FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(), 833234353Sdim IK)); 834234353Sdim } else { 835234353Sdim // Create a temporary module map file. 836234353Sdim TempModuleMapFileName = Module->Name; 837234353Sdim TempModuleMapFileName += "-%%%%%%%%.map"; 838234353Sdim int FD; 839234353Sdim if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD, 840234353Sdim TempModuleMapFileName, 841234353Sdim /*makeAbsolute=*/true) 842234353Sdim != llvm::errc::success) { 843234353Sdim ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file) 844234353Sdim << TempModuleMapFileName; 845234353Sdim return; 846234353Sdim } 847234353Sdim // Print the module map to this file. 848234353Sdim llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true); 849234353Sdim Module->print(OS); 850234353Sdim FrontendOpts.Inputs.push_back( 851234353Sdim FrontendInputFile(TempModuleMapFileName.str().str(), IK)); 852234353Sdim } 853234353Sdim 854234353Sdim // Don't free the remapped file buffers; they are owned by our caller. 855234353Sdim PPOpts.RetainRemappedFileBuffers = true; 856234353Sdim 857226633Sdim Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 858226633Sdim assert(ImportingInstance.getInvocation().getModuleHash() == 859234353Sdim Invocation->getModuleHash() && "Module hash mismatch!"); 860234353Sdim 861226633Sdim // Construct a compiler instance that will be used to actually create the 862226633Sdim // module. 863226633Sdim CompilerInstance Instance; 864226633Sdim Instance.setInvocation(&*Invocation); 865249423Sdim 866251662Sdim Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 867251662Sdim ImportingInstance.getDiagnosticClient()), 868251662Sdim /*ShouldOwnClient=*/true); 869251662Sdim 870249423Sdim // Note that this module is part of the module build stack, so that we 871249423Sdim // can detect cycles in the module graph. 872249423Sdim Instance.createFileManager(); // FIXME: Adopt file manager from importer? 873249423Sdim Instance.createSourceManager(Instance.getFileManager()); 874249423Sdim SourceManager &SourceMgr = Instance.getSourceManager(); 875249423Sdim SourceMgr.setModuleBuildStack( 876249423Sdim ImportingInstance.getSourceManager().getModuleBuildStack()); 877249423Sdim SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 878249423Sdim FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 879249423Sdim 880249423Sdim 881226633Sdim // Construct a module-generating action. 882234353Sdim GenerateModuleAction CreateModuleAction; 883234353Sdim 884226633Sdim // Execute the action to actually build the module in-place. Use a separate 885226633Sdim // thread so that we get a stack large enough. 886226633Sdim const unsigned ThreadStackSize = 8 << 20; 887226633Sdim llvm::CrashRecoveryContext CRC; 888234353Sdim CompileModuleMapData Data = { Instance, CreateModuleAction }; 889234353Sdim CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize); 890251662Sdim 891234353Sdim 892234353Sdim // Delete the temporary module map file. 893234353Sdim // FIXME: Even though we're executing under crash protection, it would still 894234353Sdim // be nice to do this with RemoveFileOnSignal when we can. However, that 895234353Sdim // doesn't make sense for all clients, so clean this up manually. 896243830Sdim Instance.clearOutputFiles(/*EraseFiles=*/true); 897234353Sdim if (!TempModuleMapFileName.empty()) 898234353Sdim llvm::sys::Path(TempModuleMapFileName).eraseFromDisk(); 899249423Sdim 900249423Sdim // We've rebuilt a module. If we're allowed to generate or update the global 901249423Sdim // module index, record that fact in the importing compiler instance. 902249423Sdim if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 903249423Sdim ImportingInstance.setBuildGlobalModuleIndex(true); 904249423Sdim } 905226633Sdim} 906226633Sdim 907249423Sdim/// \brief Diagnose differences between the current definition of the given 908249423Sdim/// configuration macro and the definition provided on the command line. 909249423Sdimstatic void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 910249423Sdim Module *Mod, SourceLocation ImportLoc) { 911249423Sdim IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 912249423Sdim SourceManager &SourceMgr = PP.getSourceManager(); 913249423Sdim 914249423Sdim // If this identifier has never had a macro definition, then it could 915249423Sdim // not have changed. 916249423Sdim if (!Id->hadMacroDefinition()) 917249423Sdim return; 918249423Sdim 919249423Sdim // If this identifier does not currently have a macro definition, 920249423Sdim // check whether it had one on the command line. 921249423Sdim if (!Id->hasMacroDefinition()) { 922249423Sdim MacroDirective::DefInfo LatestDef = 923249423Sdim PP.getMacroDirectiveHistory(Id)->getDefinition(); 924249423Sdim for (MacroDirective::DefInfo Def = LatestDef; Def; 925249423Sdim Def = Def.getPreviousDefinition()) { 926249423Sdim FileID FID = SourceMgr.getFileID(Def.getLocation()); 927249423Sdim if (FID.isInvalid()) 928249423Sdim continue; 929249423Sdim 930249423Sdim // We only care about the predefines buffer. 931249423Sdim if (FID != PP.getPredefinesFileID()) 932249423Sdim continue; 933249423Sdim 934249423Sdim // This macro was defined on the command line, then #undef'd later. 935249423Sdim // Complain. 936249423Sdim PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 937249423Sdim << true << ConfigMacro << Mod->getFullModuleName(); 938249423Sdim if (LatestDef.isUndefined()) 939249423Sdim PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 940249423Sdim << true; 941249423Sdim return; 942249423Sdim } 943249423Sdim 944249423Sdim // Okay: no definition in the predefines buffer. 945249423Sdim return; 946249423Sdim } 947249423Sdim 948249423Sdim // This identifier has a macro definition. Check whether we had a definition 949249423Sdim // on the command line. 950249423Sdim MacroDirective::DefInfo LatestDef = 951249423Sdim PP.getMacroDirectiveHistory(Id)->getDefinition(); 952249423Sdim MacroDirective::DefInfo PredefinedDef; 953249423Sdim for (MacroDirective::DefInfo Def = LatestDef; Def; 954249423Sdim Def = Def.getPreviousDefinition()) { 955249423Sdim FileID FID = SourceMgr.getFileID(Def.getLocation()); 956249423Sdim if (FID.isInvalid()) 957249423Sdim continue; 958249423Sdim 959249423Sdim // We only care about the predefines buffer. 960249423Sdim if (FID != PP.getPredefinesFileID()) 961249423Sdim continue; 962249423Sdim 963249423Sdim PredefinedDef = Def; 964249423Sdim break; 965249423Sdim } 966249423Sdim 967249423Sdim // If there was no definition for this macro in the predefines buffer, 968249423Sdim // complain. 969249423Sdim if (!PredefinedDef || 970249423Sdim (!PredefinedDef.getLocation().isValid() && 971249423Sdim PredefinedDef.getUndefLocation().isValid())) { 972249423Sdim PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 973249423Sdim << false << ConfigMacro << Mod->getFullModuleName(); 974249423Sdim PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 975249423Sdim << false; 976249423Sdim return; 977249423Sdim } 978249423Sdim 979249423Sdim // If the current macro definition is the same as the predefined macro 980249423Sdim // definition, it's okay. 981249423Sdim if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() || 982249423Sdim LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP, 983249423Sdim /*Syntactically=*/true)) 984249423Sdim return; 985249423Sdim 986249423Sdim // The macro definitions differ. 987249423Sdim PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 988249423Sdim << false << ConfigMacro << Mod->getFullModuleName(); 989249423Sdim PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 990249423Sdim << false; 991249423Sdim} 992249423Sdim 993249423Sdim/// \brief Write a new timestamp file with the given path. 994249423Sdimstatic void writeTimestampFile(StringRef TimestampFile) { 995249423Sdim std::string ErrorInfo; 996249423Sdim llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo, 997249423Sdim llvm::raw_fd_ostream::F_Binary); 998249423Sdim} 999249423Sdim 1000249423Sdim/// \brief Prune the module cache of modules that haven't been accessed in 1001249423Sdim/// a long time. 1002249423Sdimstatic void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1003249423Sdim struct stat StatBuf; 1004249423Sdim llvm::SmallString<128> TimestampFile; 1005249423Sdim TimestampFile = HSOpts.ModuleCachePath; 1006249423Sdim llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1007249423Sdim 1008249423Sdim // Try to stat() the timestamp file. 1009249423Sdim if (::stat(TimestampFile.c_str(), &StatBuf)) { 1010249423Sdim // If the timestamp file wasn't there, create one now. 1011249423Sdim if (errno == ENOENT) { 1012249423Sdim writeTimestampFile(TimestampFile); 1013249423Sdim } 1014249423Sdim return; 1015249423Sdim } 1016249423Sdim 1017249423Sdim // Check whether the time stamp is older than our pruning interval. 1018249423Sdim // If not, do nothing. 1019249423Sdim time_t TimeStampModTime = StatBuf.st_mtime; 1020249423Sdim time_t CurrentTime = time(0); 1021249423Sdim if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1022249423Sdim return; 1023249423Sdim 1024249423Sdim // Write a new timestamp file so that nobody else attempts to prune. 1025249423Sdim // There is a benign race condition here, if two Clang instances happen to 1026249423Sdim // notice at the same time that the timestamp is out-of-date. 1027249423Sdim writeTimestampFile(TimestampFile); 1028249423Sdim 1029249423Sdim // Walk the entire module cache, looking for unused module files and module 1030249423Sdim // indices. 1031249423Sdim llvm::error_code EC; 1032249423Sdim SmallString<128> ModuleCachePathNative; 1033249423Sdim llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 1034249423Sdim for (llvm::sys::fs::directory_iterator 1035249423Sdim Dir(ModuleCachePathNative.str(), EC), DirEnd; 1036249423Sdim Dir != DirEnd && !EC; Dir.increment(EC)) { 1037249423Sdim // If we don't have a directory, there's nothing to look into. 1038249423Sdim bool IsDirectory; 1039249423Sdim if (llvm::sys::fs::is_directory(Dir->path(), IsDirectory) || !IsDirectory) 1040249423Sdim continue; 1041249423Sdim 1042249423Sdim // Walk all of the files within this directory. 1043249423Sdim bool RemovedAllFiles = true; 1044249423Sdim for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1045249423Sdim File != FileEnd && !EC; File.increment(EC)) { 1046249423Sdim // We only care about module and global module index files. 1047249423Sdim if (llvm::sys::path::extension(File->path()) != ".pcm" && 1048249423Sdim llvm::sys::path::filename(File->path()) != "modules.idx") { 1049249423Sdim RemovedAllFiles = false; 1050249423Sdim continue; 1051249423Sdim } 1052249423Sdim 1053249423Sdim // Look at this file. If we can't stat it, there's nothing interesting 1054249423Sdim // there. 1055249423Sdim if (::stat(File->path().c_str(), &StatBuf)) { 1056249423Sdim RemovedAllFiles = false; 1057249423Sdim continue; 1058249423Sdim } 1059249423Sdim 1060249423Sdim // If the file has been used recently enough, leave it there. 1061249423Sdim time_t FileAccessTime = StatBuf.st_atime; 1062249423Sdim if (CurrentTime - FileAccessTime <= 1063249423Sdim time_t(HSOpts.ModuleCachePruneAfter)) { 1064249423Sdim RemovedAllFiles = false; 1065249423Sdim continue; 1066249423Sdim } 1067249423Sdim 1068249423Sdim // Remove the file. 1069249423Sdim bool Existed; 1070249423Sdim if (llvm::sys::fs::remove(File->path(), Existed) || !Existed) { 1071249423Sdim RemovedAllFiles = false; 1072249423Sdim } 1073249423Sdim } 1074249423Sdim 1075249423Sdim // If we removed all of the files in the directory, remove the directory 1076249423Sdim // itself. 1077249423Sdim if (RemovedAllFiles) { 1078249423Sdim bool Existed; 1079249423Sdim llvm::sys::fs::remove(Dir->path(), Existed); 1080249423Sdim } 1081249423Sdim } 1082249423Sdim} 1083249423Sdim 1084249423SdimModuleLoadResult 1085249423SdimCompilerInstance::loadModule(SourceLocation ImportLoc, 1086249423Sdim ModuleIdPath Path, 1087249423Sdim Module::NameVisibilityKind Visibility, 1088249423Sdim bool IsInclusionDirective) { 1089234353Sdim // If we've already handled this import, just return the cached result. 1090234353Sdim // This one-element cache is important to eliminate redundant diagnostics 1091234353Sdim // when both the preprocessor and parser see the same import declaration. 1092234353Sdim if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { 1093234353Sdim // Make the named module visible. 1094234353Sdim if (LastModuleImportResult) 1095249423Sdim ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1096249423Sdim ImportLoc, /*Complain=*/false); 1097234353Sdim return LastModuleImportResult; 1098234353Sdim } 1099234353Sdim 1100226633Sdim // Determine what file we're searching from. 1101234353Sdim StringRef ModuleName = Path[0].first->getName(); 1102234353Sdim SourceLocation ModuleNameLoc = Path[0].second; 1103226633Sdim 1104234353Sdim clang::Module *Module = 0; 1105234353Sdim 1106234353Sdim // If we don't already have information on this module, load the module now. 1107234353Sdim llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 1108234353Sdim = KnownModules.find(Path[0].first); 1109234353Sdim if (Known != KnownModules.end()) { 1110234353Sdim // Retrieve the cached top-level module. 1111234353Sdim Module = Known->second; 1112234353Sdim } else if (ModuleName == getLangOpts().CurrentModule) { 1113234353Sdim // This is the module we're building. 1114234353Sdim Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); 1115234353Sdim Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 1116234353Sdim } else { 1117234353Sdim // Search for a module with the given name. 1118234353Sdim Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 1119234353Sdim std::string ModuleFileName; 1120249423Sdim if (Module) { 1121234353Sdim ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); 1122249423Sdim } else 1123234353Sdim ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); 1124226633Sdim 1125234353Sdim // If we don't already have an ASTReader, create one now. 1126234353Sdim if (!ModuleManager) { 1127234353Sdim if (!hasASTContext()) 1128234353Sdim createASTContext(); 1129226633Sdim 1130249423Sdim // If we're not recursively building a module, check whether we 1131249423Sdim // need to prune the module cache. 1132249423Sdim if (getSourceManager().getModuleBuildStack().empty() && 1133249423Sdim getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 1134249423Sdim getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 1135249423Sdim pruneModuleCache(getHeaderSearchOpts()); 1136249423Sdim } 1137249423Sdim 1138234353Sdim std::string Sysroot = getHeaderSearchOpts().Sysroot; 1139234353Sdim const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 1140234353Sdim ModuleManager = new ASTReader(getPreprocessor(), *Context, 1141234353Sdim Sysroot.empty() ? "" : Sysroot.c_str(), 1142249423Sdim PPOpts.DisablePCHValidation, 1143249423Sdim /*AllowASTWithCompilerErrors=*/false, 1144249423Sdim getFrontendOpts().UseGlobalModuleIndex); 1145234353Sdim if (hasASTConsumer()) { 1146234353Sdim ModuleManager->setDeserializationListener( 1147234353Sdim getASTConsumer().GetASTDeserializationListener()); 1148234353Sdim getASTContext().setASTMutationListener( 1149234353Sdim getASTConsumer().GetASTMutationListener()); 1150234353Sdim } 1151234353Sdim OwningPtr<ExternalASTSource> Source; 1152234353Sdim Source.reset(ModuleManager); 1153234353Sdim getASTContext().setExternalSource(Source); 1154234353Sdim if (hasSema()) 1155234353Sdim ModuleManager->InitializeSema(getSema()); 1156234353Sdim if (hasASTConsumer()) 1157234353Sdim ModuleManager->StartTranslationUnit(&getASTConsumer()); 1158234353Sdim } 1159226633Sdim 1160249423Sdim // Try to load the module file. 1161249423Sdim unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 1162249423Sdim switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, 1163249423Sdim ImportLoc, ARRFlags)) { 1164234353Sdim case ASTReader::Success: 1165234353Sdim break; 1166226633Sdim 1167243830Sdim case ASTReader::OutOfDate: { 1168249423Sdim // The module file is out-of-date. Remove it, then rebuild it. 1169243830Sdim bool Existed; 1170243830Sdim llvm::sys::fs::remove(ModuleFileName, Existed); 1171249423Sdim } 1172249423Sdim // Fall through to build the module again. 1173243830Sdim 1174249423Sdim case ASTReader::Missing: { 1175249423Sdim // The module file is (now) missing. Build it. 1176249423Sdim 1177249423Sdim // If we don't have a module, we don't know how to build the module file. 1178249423Sdim // Complain and return. 1179249423Sdim if (!Module) { 1180249423Sdim getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 1181249423Sdim << ModuleName 1182249423Sdim << SourceRange(ImportLoc, ModuleNameLoc); 1183249423Sdim ModuleBuildFailed = true; 1184249423Sdim return ModuleLoadResult(); 1185249423Sdim } 1186249423Sdim 1187249423Sdim // Check whether there is a cycle in the module graph. 1188249423Sdim ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 1189249423Sdim ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 1190249423Sdim for (; Pos != PosEnd; ++Pos) { 1191249423Sdim if (Pos->first == ModuleName) 1192249423Sdim break; 1193249423Sdim } 1194249423Sdim 1195249423Sdim if (Pos != PosEnd) { 1196249423Sdim SmallString<256> CyclePath; 1197249423Sdim for (; Pos != PosEnd; ++Pos) { 1198249423Sdim CyclePath += Pos->first; 1199249423Sdim CyclePath += " -> "; 1200249423Sdim } 1201249423Sdim CyclePath += ModuleName; 1202249423Sdim 1203249423Sdim getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 1204249423Sdim << ModuleName << CyclePath; 1205249423Sdim return ModuleLoadResult(); 1206249423Sdim } 1207249423Sdim 1208249423Sdim // Check whether we have already attempted to build this module (but 1209249423Sdim // failed). 1210249423Sdim if (getPreprocessorOpts().FailedModules && 1211249423Sdim getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 1212249423Sdim getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 1213249423Sdim << ModuleName 1214249423Sdim << SourceRange(ImportLoc, ModuleNameLoc); 1215249423Sdim ModuleBuildFailed = true; 1216249423Sdim return ModuleLoadResult(); 1217249423Sdim } 1218249423Sdim 1219249423Sdim // Try to compile the module. 1220249423Sdim compileModule(*this, ModuleNameLoc, Module, ModuleFileName); 1221249423Sdim 1222249423Sdim // Try to read the module file, now that we've compiled it. 1223249423Sdim ASTReader::ASTReadResult ReadResult 1224249423Sdim = ModuleManager->ReadAST(ModuleFileName, 1225249423Sdim serialization::MK_Module, ImportLoc, 1226249423Sdim ASTReader::ARR_Missing); 1227249423Sdim if (ReadResult != ASTReader::Success) { 1228249423Sdim if (ReadResult == ASTReader::Missing) { 1229249423Sdim getDiagnostics().Report(ModuleNameLoc, 1230249423Sdim Module? diag::err_module_not_built 1231249423Sdim : diag::err_module_not_found) 1232249423Sdim << ModuleName 1233249423Sdim << SourceRange(ImportLoc, ModuleNameLoc); 1234249423Sdim } 1235249423Sdim 1236249423Sdim if (getPreprocessorOpts().FailedModules) 1237249423Sdim getPreprocessorOpts().FailedModules->addFailed(ModuleName); 1238243830Sdim KnownModules[Path[0].first] = 0; 1239249423Sdim ModuleBuildFailed = true; 1240249423Sdim return ModuleLoadResult(); 1241243830Sdim } 1242243830Sdim 1243243830Sdim // Okay, we've rebuilt and now loaded the module. 1244243830Sdim break; 1245243830Sdim } 1246243830Sdim 1247243830Sdim case ASTReader::VersionMismatch: 1248243830Sdim case ASTReader::ConfigurationMismatch: 1249243830Sdim case ASTReader::HadErrors: 1250234353Sdim // FIXME: The ASTReader will already have complained, but can we showhorn 1251234353Sdim // that diagnostic information into a more useful form? 1252234353Sdim KnownModules[Path[0].first] = 0; 1253249423Sdim return ModuleLoadResult(); 1254234353Sdim 1255234353Sdim case ASTReader::Failure: 1256234353Sdim // Already complained, but note now that we failed. 1257234353Sdim KnownModules[Path[0].first] = 0; 1258249423Sdim ModuleBuildFailed = true; 1259249423Sdim return ModuleLoadResult(); 1260226633Sdim } 1261234353Sdim 1262234353Sdim if (!Module) { 1263234353Sdim // If we loaded the module directly, without finding a module map first, 1264234353Sdim // we'll have loaded the module's information from the module itself. 1265234353Sdim Module = PP->getHeaderSearchInfo().getModuleMap() 1266234353Sdim .findModule((Path[0].first->getName())); 1267234353Sdim } 1268243830Sdim 1269234353Sdim // Cache the result of this top-level module lookup for later. 1270234353Sdim Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 1271226633Sdim } 1272234353Sdim 1273234353Sdim // If we never found the module, fail. 1274234353Sdim if (!Module) 1275249423Sdim return ModuleLoadResult(); 1276234353Sdim 1277234353Sdim // Verify that the rest of the module path actually corresponds to 1278234353Sdim // a submodule. 1279234353Sdim if (Path.size() > 1) { 1280234353Sdim for (unsigned I = 1, N = Path.size(); I != N; ++I) { 1281234353Sdim StringRef Name = Path[I].first->getName(); 1282234353Sdim clang::Module *Sub = Module->findSubmodule(Name); 1283234353Sdim 1284234353Sdim if (!Sub) { 1285234353Sdim // Attempt to perform typo correction to find a module name that works. 1286249423Sdim SmallVector<StringRef, 2> Best; 1287234353Sdim unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 1288234353Sdim 1289234353Sdim for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1290234353Sdim JEnd = Module->submodule_end(); 1291234353Sdim J != JEnd; ++J) { 1292234353Sdim unsigned ED = Name.edit_distance((*J)->Name, 1293234353Sdim /*AllowReplacements=*/true, 1294234353Sdim BestEditDistance); 1295234353Sdim if (ED <= BestEditDistance) { 1296234353Sdim if (ED < BestEditDistance) { 1297234353Sdim Best.clear(); 1298234353Sdim BestEditDistance = ED; 1299234353Sdim } 1300234353Sdim 1301234353Sdim Best.push_back((*J)->Name); 1302234353Sdim } 1303234353Sdim } 1304234353Sdim 1305234353Sdim // If there was a clear winner, user it. 1306234353Sdim if (Best.size() == 1) { 1307234353Sdim getDiagnostics().Report(Path[I].second, 1308234353Sdim diag::err_no_submodule_suggest) 1309234353Sdim << Path[I].first << Module->getFullModuleName() << Best[0] 1310234353Sdim << SourceRange(Path[0].second, Path[I-1].second) 1311234353Sdim << FixItHint::CreateReplacement(SourceRange(Path[I].second), 1312234353Sdim Best[0]); 1313234353Sdim 1314234353Sdim Sub = Module->findSubmodule(Best[0]); 1315234353Sdim } 1316234353Sdim } 1317234353Sdim 1318234353Sdim if (!Sub) { 1319234353Sdim // No submodule by this name. Complain, and don't look for further 1320234353Sdim // submodules. 1321234353Sdim getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 1322234353Sdim << Path[I].first << Module->getFullModuleName() 1323234353Sdim << SourceRange(Path[0].second, Path[I-1].second); 1324234353Sdim break; 1325234353Sdim } 1326234353Sdim 1327234353Sdim Module = Sub; 1328234353Sdim } 1329234353Sdim } 1330234353Sdim 1331234353Sdim // Make the named module visible, if it's not already part of the module 1332234353Sdim // we are parsing. 1333234353Sdim if (ModuleName != getLangOpts().CurrentModule) { 1334234353Sdim if (!Module->IsFromModuleFile) { 1335234353Sdim // We have an umbrella header or directory that doesn't actually include 1336234353Sdim // all of the headers within the directory it covers. Complain about 1337234353Sdim // this missing submodule and recover by forgetting that we ever saw 1338234353Sdim // this submodule. 1339234353Sdim // FIXME: Should we detect this at module load time? It seems fairly 1340234353Sdim // expensive (and rare). 1341234353Sdim getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 1342234353Sdim << Module->getFullModuleName() 1343234353Sdim << SourceRange(Path.front().second, Path.back().second); 1344234353Sdim 1345249423Sdim return ModuleLoadResult(0, true); 1346234353Sdim } 1347226633Sdim 1348234353Sdim // Check whether this module is available. 1349234353Sdim StringRef Feature; 1350234353Sdim if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { 1351234353Sdim getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 1352234353Sdim << Module->getFullModuleName() 1353234353Sdim << Feature 1354234353Sdim << SourceRange(Path.front().second, Path.back().second); 1355234353Sdim LastModuleImportLoc = ImportLoc; 1356249423Sdim LastModuleImportResult = ModuleLoadResult(); 1357249423Sdim return ModuleLoadResult(); 1358234353Sdim } 1359226633Sdim 1360249423Sdim ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc, 1361249423Sdim /*Complain=*/true); 1362226633Sdim } 1363249423Sdim 1364249423Sdim // Check for any configuration macros that have changed. 1365249423Sdim clang::Module *TopModule = Module->getTopLevelModule(); 1366249423Sdim for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 1367249423Sdim checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 1368249423Sdim Module, ImportLoc); 1369249423Sdim } 1370249423Sdim 1371234353Sdim // If this module import was due to an inclusion directive, create an 1372234353Sdim // implicit import declaration to capture it in the AST. 1373234353Sdim if (IsInclusionDirective && hasASTContext()) { 1374234353Sdim TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 1375243830Sdim ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 1376243830Sdim ImportLoc, Module, 1377243830Sdim Path.back().second); 1378243830Sdim TU->addDecl(ImportD); 1379243830Sdim if (Consumer) 1380243830Sdim Consumer->HandleImplicitImportDecl(ImportD); 1381234353Sdim } 1382234353Sdim 1383234353Sdim LastModuleImportLoc = ImportLoc; 1384249423Sdim LastModuleImportResult = ModuleLoadResult(Module, false); 1385249423Sdim return LastModuleImportResult; 1386226633Sdim} 1387249423Sdim 1388249423Sdimvoid CompilerInstance::makeModuleVisible(Module *Mod, 1389249423Sdim Module::NameVisibilityKind Visibility, 1390249423Sdim SourceLocation ImportLoc, 1391249423Sdim bool Complain){ 1392249423Sdim ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); 1393249423Sdim} 1394249423Sdim 1395