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