ASTUnit.cpp revision 1458cf7089a51cdadbf843725671a677d5fc73e5
1//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// ASTUnit Implementation. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Frontend/ASTUnit.h" 15#include "clang/Frontend/PCHWriter.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/ASTConsumer.h" 18#include "clang/AST/DeclVisitor.h" 19#include "clang/AST/StmtVisitor.h" 20#include "clang/Driver/Compilation.h" 21#include "clang/Driver/Driver.h" 22#include "clang/Driver/Job.h" 23#include "clang/Driver/Tool.h" 24#include "clang/Frontend/CompilerInstance.h" 25#include "clang/Frontend/FrontendActions.h" 26#include "clang/Frontend/FrontendDiagnostic.h" 27#include "clang/Frontend/FrontendOptions.h" 28#include "clang/Frontend/PCHReader.h" 29#include "clang/Lex/HeaderSearch.h" 30#include "clang/Lex/Preprocessor.h" 31#include "clang/Basic/TargetOptions.h" 32#include "clang/Basic/TargetInfo.h" 33#include "clang/Basic/Diagnostic.h" 34#include "llvm/Support/MemoryBuffer.h" 35#include "llvm/System/Host.h" 36#include "llvm/System/Path.h" 37#include "llvm/Support/Timer.h" 38#include <cstdlib> 39#include <cstdio> 40#include <sys/stat.h> 41using namespace clang; 42 43ASTUnit::ASTUnit(bool _MainFileIsAST) 44 : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), 45 ConcurrencyCheckValue(CheckUnlocked), SavedMainFileBuffer(0) { 46} 47 48ASTUnit::~ASTUnit() { 49 ConcurrencyCheckValue = CheckLocked; 50 CleanTemporaryFiles(); 51 if (!PreambleFile.empty()) 52 llvm::sys::Path(PreambleFile).eraseFromDisk(); 53 54 // Free the buffers associated with remapped files. We are required to 55 // perform this operation here because we explicitly request that the 56 // compiler instance *not* free these buffers for each invocation of the 57 // parser. 58 if (Invocation.get()) { 59 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 60 for (PreprocessorOptions::remapped_file_buffer_iterator 61 FB = PPOpts.remapped_file_buffer_begin(), 62 FBEnd = PPOpts.remapped_file_buffer_end(); 63 FB != FBEnd; 64 ++FB) 65 delete FB->second; 66 } 67 68 delete SavedMainFileBuffer; 69 70 for (unsigned I = 0, N = Timers.size(); I != N; ++I) 71 delete Timers[I]; 72} 73 74void ASTUnit::CleanTemporaryFiles() { 75 for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 76 TemporaryFiles[I].eraseFromDisk(); 77 TemporaryFiles.clear(); 78} 79 80namespace { 81 82/// \brief Gathers information from PCHReader that will be used to initialize 83/// a Preprocessor. 84class PCHInfoCollector : public PCHReaderListener { 85 LangOptions &LangOpt; 86 HeaderSearch &HSI; 87 std::string &TargetTriple; 88 std::string &Predefines; 89 unsigned &Counter; 90 91 unsigned NumHeaderInfos; 92 93public: 94 PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 95 std::string &TargetTriple, std::string &Predefines, 96 unsigned &Counter) 97 : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 98 Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 99 100 virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 101 LangOpt = LangOpts; 102 return false; 103 } 104 105 virtual bool ReadTargetTriple(llvm::StringRef Triple) { 106 TargetTriple = Triple; 107 return false; 108 } 109 110 virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 111 llvm::StringRef OriginalFileName, 112 std::string &SuggestedPredefines) { 113 Predefines = Buffers[0].Data; 114 for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 115 Predefines += Buffers[I].Data; 116 } 117 return false; 118 } 119 120 virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 121 HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 122 } 123 124 virtual void ReadCounter(unsigned Value) { 125 Counter = Value; 126 } 127}; 128 129class StoredDiagnosticClient : public DiagnosticClient { 130 llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags; 131 132public: 133 explicit StoredDiagnosticClient( 134 llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 135 : StoredDiags(StoredDiags) { } 136 137 virtual void HandleDiagnostic(Diagnostic::Level Level, 138 const DiagnosticInfo &Info); 139}; 140 141/// \brief RAII object that optionally captures diagnostics, if 142/// there is no diagnostic client to capture them already. 143class CaptureDroppedDiagnostics { 144 Diagnostic &Diags; 145 StoredDiagnosticClient Client; 146 DiagnosticClient *PreviousClient; 147 148public: 149 CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 150 llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 151 : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient()) 152 { 153 if (RequestCapture || Diags.getClient() == 0) 154 Diags.setClient(&Client); 155 } 156 157 ~CaptureDroppedDiagnostics() { 158 Diags.setClient(PreviousClient); 159 } 160}; 161 162} // anonymous namespace 163 164void StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level, 165 const DiagnosticInfo &Info) { 166 StoredDiags.push_back(StoredDiagnostic(Level, Info)); 167} 168 169const std::string &ASTUnit::getOriginalSourceFileName() { 170 return OriginalSourceFile; 171} 172 173const std::string &ASTUnit::getPCHFileName() { 174 assert(isMainFileAST() && "Not an ASTUnit from a PCH file!"); 175 return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName(); 176} 177 178ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, 179 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 180 bool OnlyLocalDecls, 181 RemappedFile *RemappedFiles, 182 unsigned NumRemappedFiles, 183 bool CaptureDiagnostics) { 184 llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 185 186 if (!Diags.getPtr()) { 187 // No diagnostics engine was provided, so create our own diagnostics object 188 // with the default options. 189 DiagnosticOptions DiagOpts; 190 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 191 } 192 193 AST->CaptureDiagnostics = CaptureDiagnostics; 194 AST->OnlyLocalDecls = OnlyLocalDecls; 195 AST->Diagnostics = Diags; 196 AST->FileMgr.reset(new FileManager); 197 AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics())); 198 AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 199 200 // If requested, capture diagnostics in the ASTUnit. 201 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(), 202 AST->StoredDiagnostics); 203 204 for (unsigned I = 0; I != NumRemappedFiles; ++I) { 205 // Create the file entry for the file that we're mapping from. 206 const FileEntry *FromFile 207 = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 208 RemappedFiles[I].second->getBufferSize(), 209 0); 210 if (!FromFile) { 211 AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 212 << RemappedFiles[I].first; 213 delete RemappedFiles[I].second; 214 continue; 215 } 216 217 // Override the contents of the "from" file with the contents of 218 // the "to" file. 219 AST->getSourceManager().overrideFileContents(FromFile, 220 RemappedFiles[I].second); 221 } 222 223 // Gather Info for preprocessor construction later on. 224 225 LangOptions LangInfo; 226 HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 227 std::string TargetTriple; 228 std::string Predefines; 229 unsigned Counter; 230 231 llvm::OwningPtr<PCHReader> Reader; 232 llvm::OwningPtr<ExternalASTSource> Source; 233 234 Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), 235 AST->getDiagnostics())); 236 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, 237 Predefines, Counter)); 238 239 switch (Reader->ReadPCH(Filename)) { 240 case PCHReader::Success: 241 break; 242 243 case PCHReader::Failure: 244 case PCHReader::IgnorePCH: 245 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 246 return NULL; 247 } 248 249 AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 250 251 // PCH loaded successfully. Now create the preprocessor. 252 253 // Get information about the target being compiled for. 254 // 255 // FIXME: This is broken, we should store the TargetOptions in the PCH. 256 TargetOptions TargetOpts; 257 TargetOpts.ABI = ""; 258 TargetOpts.CXXABI = "itanium"; 259 TargetOpts.CPU = ""; 260 TargetOpts.Features.clear(); 261 TargetOpts.Triple = TargetTriple; 262 AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(), 263 TargetOpts)); 264 AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo, 265 *AST->Target.get(), 266 AST->getSourceManager(), HeaderInfo)); 267 Preprocessor &PP = *AST->PP.get(); 268 269 PP.setPredefines(Reader->getSuggestedPredefines()); 270 PP.setCounterValue(Counter); 271 Reader->setPreprocessor(PP); 272 273 // Create and initialize the ASTContext. 274 275 AST->Ctx.reset(new ASTContext(LangInfo, 276 AST->getSourceManager(), 277 *AST->Target.get(), 278 PP.getIdentifierTable(), 279 PP.getSelectorTable(), 280 PP.getBuiltinInfo(), 281 /* size_reserve = */0)); 282 ASTContext &Context = *AST->Ctx.get(); 283 284 Reader->InitializeContext(Context); 285 286 // Attach the PCH reader to the AST context as an external AST 287 // source, so that declarations will be deserialized from the 288 // PCH file as needed. 289 Source.reset(Reader.take()); 290 Context.setExternalSource(Source); 291 292 return AST.take(); 293} 294 295namespace { 296 297class TopLevelDeclTrackerConsumer : public ASTConsumer { 298 ASTUnit &Unit; 299 300public: 301 TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {} 302 303 void HandleTopLevelDecl(DeclGroupRef D) { 304 for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 305 Decl *D = *it; 306 // FIXME: Currently ObjC method declarations are incorrectly being 307 // reported as top-level declarations, even though their DeclContext 308 // is the containing ObjC @interface/@implementation. This is a 309 // fundamental problem in the parser right now. 310 if (isa<ObjCMethodDecl>(D)) 311 continue; 312 Unit.getTopLevelDecls().push_back(D); 313 } 314 } 315}; 316 317class TopLevelDeclTrackerAction : public ASTFrontendAction { 318public: 319 ASTUnit &Unit; 320 321 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 322 llvm::StringRef InFile) { 323 return new TopLevelDeclTrackerConsumer(Unit); 324 } 325 326public: 327 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 328 329 virtual bool hasCodeCompletionSupport() const { return false; } 330}; 331 332class PrecompilePreambleConsumer : public PCHGenerator { 333 ASTUnit &Unit; 334 335public: 336 PrecompilePreambleConsumer(ASTUnit &Unit, 337 const Preprocessor &PP, bool Chaining, 338 const char *isysroot, llvm::raw_ostream *Out) 339 : PCHGenerator(PP, Chaining, isysroot, Out), Unit(Unit) { } 340 341 void HandleTopLevelDecl(DeclGroupRef D) { 342 for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 343 Decl *D = *it; 344 // FIXME: Currently ObjC method declarations are incorrectly being 345 // reported as top-level declarations, even though their DeclContext 346 // is the containing ObjC @interface/@implementation. This is a 347 // fundamental problem in the parser right now. 348 if (isa<ObjCMethodDecl>(D)) 349 continue; 350 Unit.getTopLevelDecls().push_back(D); 351 } 352 } 353}; 354 355class PrecompilePreambleAction : public ASTFrontendAction { 356 ASTUnit &Unit; 357 358public: 359 explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 360 361 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 362 llvm::StringRef InFile) { 363 std::string Sysroot; 364 llvm::raw_ostream *OS = 0; 365 bool Chaining; 366 if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 367 OS, Chaining)) 368 return 0; 369 370 const char *isysroot = CI.getFrontendOpts().RelocatablePCH ? 371 Sysroot.c_str() : 0; 372 return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining, 373 isysroot, OS); 374 } 375 376 virtual bool hasCodeCompletionSupport() const { return false; } 377 virtual bool hasASTFileSupport() const { return false; } 378}; 379 380} 381 382/// Parse the source file into a translation unit using the given compiler 383/// invocation, replacing the current translation unit. 384/// 385/// \returns True if a failure occurred that causes the ASTUnit not to 386/// contain any translation-unit information, false otherwise. 387bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 388 delete SavedMainFileBuffer; 389 SavedMainFileBuffer = 0; 390 391 if (!Invocation.get()) 392 return true; 393 394 // Create the compiler instance to use for building the AST. 395 CompilerInstance Clang; 396 Clang.setInvocation(Invocation.take()); 397 OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 398 399 // Set up diagnostics. 400 Clang.setDiagnostics(&getDiagnostics()); 401 Clang.setDiagnosticClient(getDiagnostics().getClient()); 402 403 // Create the target instance. 404 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 405 Clang.getTargetOpts())); 406 if (!Clang.hasTarget()) { 407 Clang.takeDiagnosticClient(); 408 return true; 409 } 410 411 // Inform the target of the language options. 412 // 413 // FIXME: We shouldn't need to do this, the target should be immutable once 414 // created. This complexity should be lifted elsewhere. 415 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 416 417 assert(Clang.getFrontendOpts().Inputs.size() == 1 && 418 "Invocation must have exactly one source file!"); 419 assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 420 "FIXME: AST inputs not yet supported here!"); 421 assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 422 "IR inputs not support here!"); 423 424 // Configure the various subsystems. 425 // FIXME: Should we retain the previous file manager? 426 FileMgr.reset(new FileManager); 427 SourceMgr.reset(new SourceManager(getDiagnostics())); 428 Ctx.reset(); 429 PP.reset(); 430 431 // Clear out old caches and data. 432 TopLevelDecls.clear(); 433 CleanTemporaryFiles(); 434 PreprocessedEntitiesByFile.clear(); 435 436 if (!OverrideMainBuffer) 437 StoredDiagnostics.clear(); 438 439 // Capture any diagnostics that would otherwise be dropped. 440 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 441 Clang.getDiagnostics(), 442 StoredDiagnostics); 443 444 // Create a file manager object to provide access to and cache the filesystem. 445 Clang.setFileManager(&getFileManager()); 446 447 // Create the source manager. 448 Clang.setSourceManager(&getSourceManager()); 449 450 // If the main file has been overridden due to the use of a preamble, 451 // make that override happen and introduce the preamble. 452 PreprocessorOptions &PreprocessorOpts = Clang.getPreprocessorOpts(); 453 if (OverrideMainBuffer) { 454 PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 455 PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 456 PreprocessorOpts.PrecompiledPreambleBytes.second 457 = PreambleEndsAtStartOfLine; 458 PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 459 PreprocessorOpts.DisablePCHValidation = true; 460 461 // Keep track of the override buffer; 462 SavedMainFileBuffer = OverrideMainBuffer; 463 464 // The stored diagnostic has the old source manager in it; update 465 // the locations to refer into the new source manager. Since we've 466 // been careful to make sure that the source manager's state 467 // before and after are identical, so that we can reuse the source 468 // location itself. 469 for (unsigned I = 0, N = StoredDiagnostics.size(); I != N; ++I) { 470 FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), 471 getSourceManager()); 472 StoredDiagnostics[I].setLocation(Loc); 473 } 474 } 475 476 llvm::OwningPtr<TopLevelDeclTrackerAction> Act; 477 Act.reset(new TopLevelDeclTrackerAction(*this)); 478 if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 479 Clang.getFrontendOpts().Inputs[0].first)) 480 goto error; 481 482 Act->Execute(); 483 484 // Steal the created target, context, and preprocessor, and take back the 485 // source and file managers. 486 Ctx.reset(Clang.takeASTContext()); 487 PP.reset(Clang.takePreprocessor()); 488 Clang.takeSourceManager(); 489 Clang.takeFileManager(); 490 Target.reset(Clang.takeTarget()); 491 492 Act->EndSourceFile(); 493 494 // Remove the overridden buffer we used for the preamble. 495 if (OverrideMainBuffer) 496 PreprocessorOpts.eraseRemappedFile( 497 PreprocessorOpts.remapped_file_buffer_end() - 1); 498 499 Clang.takeDiagnosticClient(); 500 501 Invocation.reset(Clang.takeInvocation()); 502 return false; 503 504error: 505 // Remove the overridden buffer we used for the preamble. 506 if (OverrideMainBuffer) { 507 PreprocessorOpts.eraseRemappedFile( 508 PreprocessorOpts.remapped_file_buffer_end() - 1); 509 PreprocessorOpts.DisablePCHValidation = true; 510 } 511 512 Clang.takeSourceManager(); 513 Clang.takeFileManager(); 514 Clang.takeDiagnosticClient(); 515 Invocation.reset(Clang.takeInvocation()); 516 return true; 517} 518 519/// \brief Simple function to retrieve a path for a preamble precompiled header. 520static std::string GetPreamblePCHPath() { 521 // FIXME: This is lame; sys::Path should provide this function (in particular, 522 // it should know how to find the temporary files dir). 523 // FIXME: This is really lame. I copied this code from the Driver! 524 std::string Error; 525 const char *TmpDir = ::getenv("TMPDIR"); 526 if (!TmpDir) 527 TmpDir = ::getenv("TEMP"); 528 if (!TmpDir) 529 TmpDir = ::getenv("TMP"); 530 if (!TmpDir) 531 TmpDir = "/tmp"; 532 llvm::sys::Path P(TmpDir); 533 P.appendComponent("preamble"); 534 if (P.createTemporaryFileOnDisk()) 535 return std::string(); 536 537 P.appendSuffix("pch"); 538 return P.str(); 539} 540 541/// \brief Compute the preamble for the main file, providing the source buffer 542/// that corresponds to the main file along with a pair (bytes, start-of-line) 543/// that describes the preamble. 544std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 545ASTUnit::ComputePreamble(CompilerInvocation &Invocation, bool &CreatedBuffer) { 546 FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 547 PreprocessorOptions &PreprocessorOpts 548 = Invocation.getPreprocessorOpts(); 549 CreatedBuffer = false; 550 551 // Try to determine if the main file has been remapped, either from the 552 // command line (to another file) or directly through the compiler invocation 553 // (to a memory buffer). 554 llvm::MemoryBuffer *Buffer = 0; 555 llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 556 if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 557 // Check whether there is a file-file remapping of the main file 558 for (PreprocessorOptions::remapped_file_iterator 559 M = PreprocessorOpts.remapped_file_begin(), 560 E = PreprocessorOpts.remapped_file_end(); 561 M != E; 562 ++M) { 563 llvm::sys::PathWithStatus MPath(M->first); 564 if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 565 if (MainFileStatus->uniqueID == MStatus->uniqueID) { 566 // We found a remapping. Try to load the resulting, remapped source. 567 if (CreatedBuffer) { 568 delete Buffer; 569 CreatedBuffer = false; 570 } 571 572 Buffer = llvm::MemoryBuffer::getFile(M->second); 573 if (!Buffer) 574 return std::make_pair((llvm::MemoryBuffer*)0, 575 std::make_pair(0, true)); 576 CreatedBuffer = true; 577 578 // Remove this remapping. We've captured the buffer already. 579 M = PreprocessorOpts.eraseRemappedFile(M); 580 E = PreprocessorOpts.remapped_file_end(); 581 } 582 } 583 } 584 585 // Check whether there is a file-buffer remapping. It supercedes the 586 // file-file remapping. 587 for (PreprocessorOptions::remapped_file_buffer_iterator 588 M = PreprocessorOpts.remapped_file_buffer_begin(), 589 E = PreprocessorOpts.remapped_file_buffer_end(); 590 M != E; 591 ++M) { 592 llvm::sys::PathWithStatus MPath(M->first); 593 if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 594 if (MainFileStatus->uniqueID == MStatus->uniqueID) { 595 // We found a remapping. 596 if (CreatedBuffer) { 597 delete Buffer; 598 CreatedBuffer = false; 599 } 600 601 Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 602 603 // Remove this remapping. We've captured the buffer already. 604 M = PreprocessorOpts.eraseRemappedFile(M); 605 E = PreprocessorOpts.remapped_file_buffer_end(); 606 } 607 } 608 } 609 } 610 611 // If the main source file was not remapped, load it now. 612 if (!Buffer) { 613 Buffer = llvm::MemoryBuffer::getFile(FrontendOpts.Inputs[0].second); 614 if (!Buffer) 615 return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 616 617 CreatedBuffer = true; 618 } 619 620 return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer)); 621} 622 623static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 624 bool DeleteOld, 625 unsigned NewSize, 626 llvm::StringRef NewName) { 627 llvm::MemoryBuffer *Result 628 = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 629 memcpy(const_cast<char*>(Result->getBufferStart()), 630 Old->getBufferStart(), Old->getBufferSize()); 631 memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 632 ' ', NewSize - Old->getBufferSize() - 1); 633 const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 634 635 if (DeleteOld) 636 delete Old; 637 638 return Result; 639} 640 641/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 642/// the source file. 643/// 644/// This routine will compute the preamble of the main source file. If a 645/// non-trivial preamble is found, it will precompile that preamble into a 646/// precompiled header so that the precompiled preamble can be used to reduce 647/// reparsing time. If a precompiled preamble has already been constructed, 648/// this routine will determine if it is still valid and, if so, avoid 649/// rebuilding the precompiled preamble. 650/// 651/// \returns If the precompiled preamble can be used, returns a newly-allocated 652/// buffer that should be used in place of the main file when doing so. 653/// Otherwise, returns a NULL pointer. 654llvm::MemoryBuffer *ASTUnit::BuildPrecompiledPreamble() { 655 CompilerInvocation PreambleInvocation(*Invocation); 656 FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts(); 657 PreprocessorOptions &PreprocessorOpts 658 = PreambleInvocation.getPreprocessorOpts(); 659 660 bool CreatedPreambleBuffer = false; 661 std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 662 = ComputePreamble(PreambleInvocation, CreatedPreambleBuffer); 663 664 if (!NewPreamble.second.first) { 665 // We couldn't find a preamble in the main source. Clear out the current 666 // preamble, if we have one. It's obviously no good any more. 667 Preamble.clear(); 668 if (!PreambleFile.empty()) { 669 llvm::sys::Path(PreambleFile).eraseFromDisk(); 670 PreambleFile.clear(); 671 } 672 if (CreatedPreambleBuffer) 673 delete NewPreamble.first; 674 675 return 0; 676 } 677 678 if (!Preamble.empty()) { 679 // We've previously computed a preamble. Check whether we have the same 680 // preamble now that we did before, and that there's enough space in 681 // the main-file buffer within the precompiled preamble to fit the 682 // new main file. 683 if (Preamble.size() == NewPreamble.second.first && 684 PreambleEndsAtStartOfLine == NewPreamble.second.second && 685 NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 686 memcmp(&Preamble[0], NewPreamble.first->getBufferStart(), 687 NewPreamble.second.first) == 0) { 688 // The preamble has not changed. We may be able to re-use the precompiled 689 // preamble. 690 691 // Check that none of the files used by the preamble have changed. 692 bool AnyFileChanged = false; 693 694 // First, make a record of those files that have been overridden via 695 // remapping or unsaved_files. 696 llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 697 for (PreprocessorOptions::remapped_file_iterator 698 R = PreprocessorOpts.remapped_file_begin(), 699 REnd = PreprocessorOpts.remapped_file_end(); 700 !AnyFileChanged && R != REnd; 701 ++R) { 702 struct stat StatBuf; 703 if (stat(R->second.c_str(), &StatBuf)) { 704 // If we can't stat the file we're remapping to, assume that something 705 // horrible happened. 706 AnyFileChanged = true; 707 break; 708 } 709 710 OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 711 StatBuf.st_mtime); 712 } 713 for (PreprocessorOptions::remapped_file_buffer_iterator 714 R = PreprocessorOpts.remapped_file_buffer_begin(), 715 REnd = PreprocessorOpts.remapped_file_buffer_end(); 716 !AnyFileChanged && R != REnd; 717 ++R) { 718 // FIXME: Should we actually compare the contents of file->buffer 719 // remappings? 720 OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 721 0); 722 } 723 724 // Check whether anything has changed. 725 for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 726 F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 727 !AnyFileChanged && F != FEnd; 728 ++F) { 729 llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 730 = OverriddenFiles.find(F->first()); 731 if (Overridden != OverriddenFiles.end()) { 732 // This file was remapped; check whether the newly-mapped file 733 // matches up with the previous mapping. 734 if (Overridden->second != F->second) 735 AnyFileChanged = true; 736 continue; 737 } 738 739 // The file was not remapped; check whether it has changed on disk. 740 struct stat StatBuf; 741 if (stat(F->first(), &StatBuf)) { 742 // If we can't stat the file, assume that something horrible happened. 743 AnyFileChanged = true; 744 } else if (StatBuf.st_size != F->second.first || 745 StatBuf.st_mtime != F->second.second) 746 AnyFileChanged = true; 747 } 748 749 if (!AnyFileChanged) { 750 // Okay! We can re-use the precompiled preamble. 751 752 // Set the state of the diagnostic object to mimic its state 753 // after parsing the preamble. 754 getDiagnostics().Reset(); 755 getDiagnostics().setNumWarnings(NumWarningsInPreamble); 756 if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble) 757 StoredDiagnostics.erase( 758 StoredDiagnostics.begin() + NumStoredDiagnosticsInPreamble, 759 StoredDiagnostics.end()); 760 761 // Create a version of the main file buffer that is padded to 762 // buffer size we reserved when creating the preamble. 763 return CreatePaddedMainFileBuffer(NewPreamble.first, 764 CreatedPreambleBuffer, 765 PreambleReservedSize, 766 FrontendOpts.Inputs[0].second); 767 } 768 } 769 770 // We can't reuse the previously-computed preamble. Build a new one. 771 Preamble.clear(); 772 llvm::sys::Path(PreambleFile).eraseFromDisk(); 773 } 774 775 // We did not previously compute a preamble, or it can't be reused anyway. 776 llvm::Timer *PreambleTimer = 0; 777 if (TimerGroup.get()) { 778 PreambleTimer = new llvm::Timer("Precompiling preamble", *TimerGroup); 779 PreambleTimer->startTimer(); 780 Timers.push_back(PreambleTimer); 781 } 782 783 // Create a new buffer that stores the preamble. The buffer also contains 784 // extra space for the original contents of the file (which will be present 785 // when we actually parse the file) along with more room in case the file 786 // grows. 787 PreambleReservedSize = NewPreamble.first->getBufferSize(); 788 if (PreambleReservedSize < 4096) 789 PreambleReservedSize = 8191; 790 else 791 PreambleReservedSize *= 2; 792 793 // Save the preamble text for later; we'll need to compare against it for 794 // subsequent reparses. 795 Preamble.assign(NewPreamble.first->getBufferStart(), 796 NewPreamble.first->getBufferStart() 797 + NewPreamble.second.first); 798 PreambleEndsAtStartOfLine = NewPreamble.second.second; 799 800 llvm::MemoryBuffer *PreambleBuffer 801 = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 802 FrontendOpts.Inputs[0].second); 803 memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 804 NewPreamble.first->getBufferStart(), Preamble.size()); 805 memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 806 ' ', PreambleReservedSize - Preamble.size() - 1); 807 const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 808 809 // Remap the main source file to the preamble buffer. 810 llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 811 PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 812 813 // Tell the compiler invocation to generate a temporary precompiled header. 814 FrontendOpts.ProgramAction = frontend::GeneratePCH; 815 // FIXME: Set ChainedPCH, once it is ready. 816 // FIXME: Generate the precompiled header into memory? 817 FrontendOpts.OutputFile = GetPreamblePCHPath(); 818 819 // Create the compiler instance to use for building the precompiled preamble. 820 CompilerInstance Clang; 821 Clang.setInvocation(&PreambleInvocation); 822 OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 823 824 // Set up diagnostics. 825 Clang.setDiagnostics(&getDiagnostics()); 826 Clang.setDiagnosticClient(getDiagnostics().getClient()); 827 828 // Create the target instance. 829 Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 830 Clang.getTargetOpts())); 831 if (!Clang.hasTarget()) { 832 Clang.takeDiagnosticClient(); 833 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 834 Preamble.clear(); 835 if (CreatedPreambleBuffer) 836 delete NewPreamble.first; 837 if (PreambleTimer) 838 PreambleTimer->stopTimer(); 839 840 return 0; 841 } 842 843 // Inform the target of the language options. 844 // 845 // FIXME: We shouldn't need to do this, the target should be immutable once 846 // created. This complexity should be lifted elsewhere. 847 Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 848 849 assert(Clang.getFrontendOpts().Inputs.size() == 1 && 850 "Invocation must have exactly one source file!"); 851 assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 852 "FIXME: AST inputs not yet supported here!"); 853 assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 854 "IR inputs not support here!"); 855 856 // Clear out old caches and data. 857 StoredDiagnostics.clear(); 858 859 // Capture any diagnostics that would otherwise be dropped. 860 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 861 getDiagnostics(), 862 StoredDiagnostics); 863 864 // Create a file manager object to provide access to and cache the filesystem. 865 Clang.setFileManager(new FileManager); 866 867 // Create the source manager. 868 Clang.setSourceManager(new SourceManager(getDiagnostics())); 869 870 // FIXME: Eventually, we'll have to track top-level declarations here, too. 871 llvm::OwningPtr<PrecompilePreambleAction> Act; 872 Act.reset(new PrecompilePreambleAction(*this)); 873 if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 874 Clang.getFrontendOpts().Inputs[0].first)) { 875 Clang.takeDiagnosticClient(); 876 Clang.takeInvocation(); 877 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 878 Preamble.clear(); 879 if (CreatedPreambleBuffer) 880 delete NewPreamble.first; 881 if (PreambleTimer) 882 PreambleTimer->stopTimer(); 883 884 return 0; 885 } 886 887 Act->Execute(); 888 Act->EndSourceFile(); 889 Clang.takeDiagnosticClient(); 890 Clang.takeInvocation(); 891 892 if (Diagnostics->getNumErrors() > 0) { 893 // There were errors parsing the preamble, so no precompiled header was 894 // generated. Forget that we even tried. 895 // FIXME: Should we leave a note for ourselves to try again? 896 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 897 Preamble.clear(); 898 if (CreatedPreambleBuffer) 899 delete NewPreamble.first; 900 if (PreambleTimer) 901 PreambleTimer->stopTimer(); 902 903 return 0; 904 } 905 906 // Keep track of the preamble we precompiled. 907 PreambleFile = FrontendOpts.OutputFile; 908 NumStoredDiagnosticsInPreamble = StoredDiagnostics.size(); 909 NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 910 911 // Keep track of all of the files that the source manager knows about, 912 // so we can verify whether they have changed or not. 913 FilesInPreamble.clear(); 914 SourceManager &SourceMgr = Clang.getSourceManager(); 915 const llvm::MemoryBuffer *MainFileBuffer 916 = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 917 for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 918 FEnd = SourceMgr.fileinfo_end(); 919 F != FEnd; 920 ++F) { 921 const FileEntry *File = F->second->Entry; 922 if (!File || F->second->getRawBuffer() == MainFileBuffer) 923 continue; 924 925 FilesInPreamble[File->getName()] 926 = std::make_pair(F->second->getSize(), File->getModificationTime()); 927 } 928 929 if (PreambleTimer) 930 PreambleTimer->stopTimer(); 931 932 return CreatePaddedMainFileBuffer(NewPreamble.first, 933 CreatedPreambleBuffer, 934 PreambleReservedSize, 935 FrontendOpts.Inputs[0].second); 936} 937 938ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 939 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 940 bool OnlyLocalDecls, 941 bool CaptureDiagnostics, 942 bool PrecompilePreamble) { 943 if (!Diags.getPtr()) { 944 // No diagnostics engine was provided, so create our own diagnostics object 945 // with the default options. 946 DiagnosticOptions DiagOpts; 947 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 948 } 949 950 // Create the AST unit. 951 llvm::OwningPtr<ASTUnit> AST; 952 AST.reset(new ASTUnit(false)); 953 AST->Diagnostics = Diags; 954 AST->CaptureDiagnostics = CaptureDiagnostics; 955 AST->OnlyLocalDecls = OnlyLocalDecls; 956 AST->Invocation.reset(CI); 957 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 958 959 if (getenv("LIBCLANG_TIMING")) 960 AST->TimerGroup.reset( 961 new llvm::TimerGroup(CI->getFrontendOpts().Inputs[0].second)); 962 963 964 llvm::MemoryBuffer *OverrideMainBuffer = 0; 965 // FIXME: When C++ PCH is ready, allow use of it for a precompiled preamble. 966 if (PrecompilePreamble && !CI->getLangOpts().CPlusPlus) 967 OverrideMainBuffer = AST->BuildPrecompiledPreamble(); 968 969 llvm::Timer *ParsingTimer = 0; 970 if (AST->TimerGroup.get()) { 971 ParsingTimer = new llvm::Timer("Initial parse", *AST->TimerGroup); 972 ParsingTimer->startTimer(); 973 AST->Timers.push_back(ParsingTimer); 974 } 975 976 bool Failed = AST->Parse(OverrideMainBuffer); 977 if (ParsingTimer) 978 ParsingTimer->stopTimer(); 979 980 return Failed? 0 : AST.take(); 981} 982 983ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 984 const char **ArgEnd, 985 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 986 llvm::StringRef ResourceFilesPath, 987 bool OnlyLocalDecls, 988 RemappedFile *RemappedFiles, 989 unsigned NumRemappedFiles, 990 bool CaptureDiagnostics, 991 bool PrecompilePreamble) { 992 if (!Diags.getPtr()) { 993 // No diagnostics engine was provided, so create our own diagnostics object 994 // with the default options. 995 DiagnosticOptions DiagOpts; 996 Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 997 } 998 999 llvm::SmallVector<const char *, 16> Args; 1000 Args.push_back("<clang>"); // FIXME: Remove dummy argument. 1001 Args.insert(Args.end(), ArgBegin, ArgEnd); 1002 1003 // FIXME: Find a cleaner way to force the driver into restricted modes. We 1004 // also want to force it to use clang. 1005 Args.push_back("-fsyntax-only"); 1006 1007 // FIXME: We shouldn't have to pass in the path info. 1008 driver::Driver TheDriver("clang", llvm::sys::getHostTriple(), 1009 "a.out", false, false, *Diags); 1010 1011 // Don't check that inputs exist, they have been remapped. 1012 TheDriver.setCheckInputsExist(false); 1013 1014 llvm::OwningPtr<driver::Compilation> C( 1015 TheDriver.BuildCompilation(Args.size(), Args.data())); 1016 1017 // We expect to get back exactly one command job, if we didn't something 1018 // failed. 1019 const driver::JobList &Jobs = C->getJobs(); 1020 if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) { 1021 llvm::SmallString<256> Msg; 1022 llvm::raw_svector_ostream OS(Msg); 1023 C->PrintJob(OS, C->getJobs(), "; ", true); 1024 Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); 1025 return 0; 1026 } 1027 1028 const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 1029 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { 1030 Diags->Report(diag::err_fe_expected_clang_command); 1031 return 0; 1032 } 1033 1034 const driver::ArgStringList &CCArgs = Cmd->getArguments(); 1035 llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation); 1036 CompilerInvocation::CreateFromArgs(*CI, 1037 const_cast<const char **>(CCArgs.data()), 1038 const_cast<const char **>(CCArgs.data()) + 1039 CCArgs.size(), 1040 *Diags); 1041 1042 // Override any files that need remapping 1043 for (unsigned I = 0; I != NumRemappedFiles; ++I) 1044 CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1045 RemappedFiles[I].second); 1046 1047 // Override the resources path. 1048 CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 1049 1050 CI->getFrontendOpts().DisableFree = true; 1051 return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls, 1052 CaptureDiagnostics, PrecompilePreamble); 1053} 1054 1055bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 1056 if (!Invocation.get()) 1057 return true; 1058 1059 llvm::Timer *ReparsingTimer = 0; 1060 if (TimerGroup.get()) { 1061 ReparsingTimer = new llvm::Timer("Reparse", *TimerGroup); 1062 ReparsingTimer->startTimer(); 1063 Timers.push_back(ReparsingTimer); 1064 } 1065 1066 // Remap files. 1067 // FIXME: Do we want to remove old mappings for these files? 1068 Invocation->getPreprocessorOpts().clearRemappedFiles(); 1069 for (unsigned I = 0; I != NumRemappedFiles; ++I) 1070 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1071 RemappedFiles[I].second); 1072 1073 // If we have a preamble file lying around, build or reuse the precompiled 1074 // preamble. 1075 llvm::MemoryBuffer *OverrideMainBuffer = 0; 1076 if (!PreambleFile.empty()) 1077 OverrideMainBuffer = BuildPrecompiledPreamble(); 1078 1079 // Clear out the diagnostics state. 1080 if (!OverrideMainBuffer) 1081 getDiagnostics().Reset(); 1082 1083 // Parse the sources 1084 bool Result = Parse(OverrideMainBuffer); 1085 if (ReparsingTimer) 1086 ReparsingTimer->stopTimer(); 1087 return Result; 1088} 1089