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