ASTUnit.cpp revision df95a13ec73d2cdaea79555cb412d767f4963120
14b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// 24b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 34b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 44b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 54b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 64b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 74b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 84b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 94b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 104b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// ASTUnit Implementation. 114b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis// 124b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 134b562cf889bc59e1914dd2c5d9fbd7e7bfa1ad77Argyrios Kyrtzidis 140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Frontend/ASTUnit.h" 151d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor#include "clang/Frontend/PCHWriter.h" 160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/ASTContext.h" 17521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/AST/ASTConsumer.h" 180853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/DeclVisitor.h" 190853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/AST/StmtVisitor.h" 207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Compilation.h" 217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Driver.h" 227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Job.h" 237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Driver/Tool.h" 24521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/CompilerInstance.h" 25521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendActions.h" 267b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "clang/Frontend/FrontendDiagnostic.h" 27521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar#include "clang/Frontend/FrontendOptions.h" 281d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor#include "clang/Frontend/PCHReader.h" 290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 31d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h" 320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 344db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 357b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "llvm/System/Host.h" 364a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer#include "llvm/System/Path.h" 37df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h" 38385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor#include "llvm/Support/Timer.h" 3944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor#include <cstdlib> 40ad23ebe22b7e52e3875981eeb46a1fd61a7554fbZhongxing Xu#include <cstdio> 41cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor#include <sys/stat.h> 420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang; 430853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 44eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// \brief After failing to build a precompiled preamble (due to 45eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// errors in the source that occurs in the preamble), the number of 46eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// reparses during which we'll skip even trying to precompile the 47eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor/// preamble. 48eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregorconst unsigned DefaultPreambleRebuildInterval = 5; 49eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 503687e9d3a5dbfa9963af02a49a2b139d91310813Douglas GregorASTUnit::ASTUnit(bool _MainFileIsAST) 51abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor : CaptureDiagnostics(false), MainFileIsAST(_MainFileIsAST), 52df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CompleteTranslationUnit(true), ConcurrencyCheckValue(CheckUnlocked), 53df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreambleRebuildCounter(0), SavedMainFileBuffer(0) { 54385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor} 553687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 56521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 57bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ConcurrencyCheckValue = CheckLocked; 58abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 59175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) 60385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 61f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 62f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Free the buffers associated with remapped files. We are required to 63f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // perform this operation here because we explicitly request that the 64f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // compiler instance *not* free these buffers for each invocation of the 65f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // parser. 66f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Invocation.get()) { 67f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 68f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 69f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB = PPOpts.remapped_file_buffer_begin(), 70f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FBEnd = PPOpts.remapped_file_buffer_end(); 71f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor FB != FBEnd; 72f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ++FB) 73f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor delete FB->second; 74f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 7528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 7628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 77385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 78385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor for (unsigned I = 0, N = Timers.size(); I != N; ++I) 79385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor delete Timers[I]; 80abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 81abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 82abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorvoid ASTUnit::CleanTemporaryFiles() { 83313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 84313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor TemporaryFiles[I].eraseFromDisk(); 85abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TemporaryFiles.clear(); 86e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// \brief Gathers information from PCHReader that will be used to initialize 910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 92bd21828179a61bd0954b082825cfb8a93345f602Benjamin Kramerclass PCHInfoCollector : public PCHReaderListener { 930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HSI; 950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple; 960853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &Predefines; 970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 990853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned NumHeaderInfos; 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1010853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 1020853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 1030853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple, std::string &Predefines, 1040853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 1050853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 1060853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1080853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 1090853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 1100853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 1110853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 113dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar virtual bool ReadTargetTriple(llvm::StringRef Triple) { 1140853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis TargetTriple = Triple; 1150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 1160853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 118cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 1197b5a1210d93ca62ecd61800f245c87259b1f8f79Daniel Dunbar llvm::StringRef OriginalFileName, 1200853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &SuggestedPredefines) { 121cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines = Buffers[0].Data; 122cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 123cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl Predefines += Buffers[I].Data; 124cb481aacdc0f08e225c68c99c65351b367042475Sebastian Redl } 1250853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 1260853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 128ec1afbfd8e880d0169aab0ececa2e7e1611f4955Douglas Gregor virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 1290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 1300853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadCounter(unsigned Value) { 1330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 1340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 1360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 137a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass StoredDiagnosticClient : public DiagnosticClient { 138a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags; 139a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 140a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 141a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor explicit StoredDiagnosticClient( 142a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 143a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor : StoredDiags(StoredDiags) { } 144a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 145a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor virtual void HandleDiagnostic(Diagnostic::Level Level, 146a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info); 147a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 148a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 149a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// \brief RAII object that optionally captures diagnostics, if 150a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor/// there is no diagnostic client to capture them already. 151a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclass CaptureDroppedDiagnostics { 152a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diagnostic &Diags; 153a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiagnosticClient Client; 154a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor DiagnosticClient *PreviousClient; 155a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 156a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorpublic: 157a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags, 158a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags) 159a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient()) 160a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor { 161a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor if (RequestCapture || Diags.getClient() == 0) 162a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(&Client); 163a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 164a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 165a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor ~CaptureDroppedDiagnostics() { 166a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Diags.setClient(PreviousClient); 167a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 168a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}; 169a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 1700853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 1710853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 172a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorvoid StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level, 173a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const DiagnosticInfo &Info) { 174a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor StoredDiags.push_back(StoredDiagnostic(Level, Info)); 175a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor} 176a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 17777accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() { 17868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar return OriginalSourceFile; 17977accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff} 1800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 181e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroffconst std::string &ASTUnit::getPCHFileName() { 182c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar assert(isMainFileAST() && "Not an ASTUnit from a PCH file!"); 1837297c18c843138625a61e01a137664a176739683Benjamin Kramer return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName(); 184e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 185e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff 1860853a02c3b04d96a3c432b883e403175c954cd81Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, 18728019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1885cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 1894db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 190a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 191a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor bool CaptureDiagnostics) { 1923687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 1933687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 19428019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 1953687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 1963687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 1973687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor DiagnosticOptions DiagOpts; 19828019772db70d4547be05a042eb950bc910f134fDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 1993687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 200abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 201abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 2027d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 20328019772db70d4547be05a042eb950bc910f134fDouglas Gregor AST->Diagnostics = Diags; 2043687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->FileMgr.reset(new FileManager); 2053687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->SourceMgr.reset(new SourceManager(AST->getDiagnostics())); 20636c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 2070853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 208a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor // If requested, capture diagnostics in the ASTUnit. 2093687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, AST->getDiagnostics(), 210405634b215f19eec7183bd8005e34aa5a02f64a1Douglas Gregor AST->StoredDiagnostics); 211a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 2124db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 2134db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Create the file entry for the file that we're mapping from. 2144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor const FileEntry *FromFile 2154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 2164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second->getBufferSize(), 2174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 0); 2184db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor if (!FromFile) { 2193687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 2204db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor << RemappedFiles[I].first; 221c8dfe5ece04e683106eb96c58a2999f70b53ac21Douglas Gregor delete RemappedFiles[I].second; 2224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor continue; 2234db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 2244db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 2254db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override the contents of the "from" file with the contents of 2264db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // the "to" file. 2274db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor AST->getSourceManager().overrideFileContents(FromFile, 2284db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second); 2294db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 2304db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 2310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2330853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions LangInfo; 2340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 2350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string TargetTriple; 2360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string Predefines; 2370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 2380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 239bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar llvm::OwningPtr<PCHReader> Reader; 2400853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis llvm::OwningPtr<ExternalASTSource> Source; 2410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 242fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), 2433687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics())); 244cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, 245cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Predefines, Counter)); 246cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 247cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar switch (Reader->ReadPCH(Filename)) { 2480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis case PCHReader::Success: 2490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis case PCHReader::Failure: 252106c9981f18084e60602244f1feaeabbbe8ab5e8Argyrios Kyrtzidis case PCHReader::IgnorePCH: 2533687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 2540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 2550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 2561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25768d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 25868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 2590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // PCH loaded successfully. Now create the preprocessor. 2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Get information about the target being compiled for. 262d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // 263d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // FIXME: This is broken, we should store the TargetOptions in the PCH. 264d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOptions TargetOpts; 265d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.ABI = ""; 26698b7c5c496dfccb39287b8f7d8f1444594936d10Charles Davis TargetOpts.CXXABI = "itanium"; 267d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.CPU = ""; 268d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Features.clear(); 269d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Triple = TargetTriple; 2703687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->Target.reset(TargetInfo::CreateTargetInfo(AST->getDiagnostics(), 2713687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor TargetOpts)); 2723687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor AST->PP.reset(new Preprocessor(AST->getDiagnostics(), LangInfo, 2733687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor *AST->Target.get(), 27431b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), HeaderInfo)); 2750853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Preprocessor &PP = *AST->PP.get(); 2760853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 277d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 2780853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 279cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setPreprocessor(PP); 2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Create and initialize the ASTContext. 2820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 2830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis AST->Ctx.reset(new ASTContext(LangInfo, 28431b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), 2850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis *AST->Target.get(), 2860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getIdentifierTable(), 2870853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getSelectorTable(), 2880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getBuiltinInfo(), 2890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis /* size_reserve = */0)); 2900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis ASTContext &Context = *AST->Ctx.get(); 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 292cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->InitializeContext(Context); 2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Attach the PCH reader to the AST context as an external AST 2950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 2960853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // PCH file as needed. 297cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Source.reset(Reader.take()); 2980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 2990853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 3010853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 302521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 303521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 304521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 305f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 306f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 307f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 308f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 309f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {} 310f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 311f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar void HandleTopLevelDecl(DeclGroupRef D) { 312da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 313da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek Decl *D = *it; 314da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // FIXME: Currently ObjC method declarations are incorrectly being 315da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // reported as top-level declarations, even though their DeclContext 316da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // is the containing ObjC @interface/@implementation. This is a 317da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek // fundamental problem in the parser right now. 318da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek if (isa<ObjCMethodDecl>(D)) 319da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek continue; 320eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDecl(D); 321da5a428bf3db404fe3c91b689cd87c68789d6db9Ted Kremenek } 322f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 323f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 324f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 325f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 326f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 327f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 328f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 329521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 330521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar llvm::StringRef InFile) { 331f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar return new TopLevelDeclTrackerConsumer(Unit); 332521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 333521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 334521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 335f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 336f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 337521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 338df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { 339df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return Unit.isCompleteTranslationUnit(); 340df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 341521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 342521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 3431d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleConsumer : public PCHGenerator { 3441d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 345eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> TopLevelDecls; 3461d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 3471d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 3481d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor PrecompilePreambleConsumer(ASTUnit &Unit, 3491d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const Preprocessor &PP, bool Chaining, 3501d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const char *isysroot, llvm::raw_ostream *Out) 3511d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor : PCHGenerator(PP, Chaining, isysroot, Out), Unit(Unit) { } 3521d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 353eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTopLevelDecl(DeclGroupRef D) { 3541d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 3551d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Decl *D = *it; 3561d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // FIXME: Currently ObjC method declarations are incorrectly being 3571d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // reported as top-level declarations, even though their DeclContext 3581d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // is the containing ObjC @interface/@implementation. This is a 3591d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor // fundamental problem in the parser right now. 3601d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (isa<ObjCMethodDecl>(D)) 3611d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor continue; 362eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.push_back(D); 363eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 364eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 365eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 366eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor virtual void HandleTranslationUnit(ASTContext &Ctx) { 367eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor PCHGenerator::HandleTranslationUnit(Ctx); 368eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!Unit.getDiagnostics().hasErrorOccurred()) { 369eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Translate the top-level declarations we captured during 370eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // parsing into declaration IDs in the precompiled 371eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // preamble. This will allow us to deserialize those top-level 372eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // declarations when requested. 373eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) 374eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Unit.addTopLevelDeclFromPreamble( 375eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor getWriter().getDeclID(TopLevelDecls[I])); 3761d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 3771d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 3781d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 3791d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 3801d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PrecompilePreambleAction : public ASTFrontendAction { 3811d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor ASTUnit &Unit; 3821d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 3831d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic: 3841d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 3851d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 3861d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 3871d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::StringRef InFile) { 3881d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor std::string Sysroot; 3891d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::raw_ostream *OS = 0; 3901d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor bool Chaining; 3911d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 3921d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor OS, Chaining)) 3931d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return 0; 3941d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 3951d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor const char *isysroot = CI.getFrontendOpts().RelocatablePCH ? 3961d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Sysroot.c_str() : 0; 3971d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Chaining, 3981d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor isysroot, OS); 3991d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor } 4001d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 4011d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasCodeCompletionSupport() const { return false; } 4021d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor virtual bool hasASTFileSupport() const { return false; } 403df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor virtual bool usesCompleteTranslationUnit() { return false; } 4041d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor}; 4051d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor 406521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 407521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 408abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// Parse the source file into a translation unit using the given compiler 409abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// invocation, replacing the current translation unit. 410abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// 411abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// \returns True if a failure occurred that causes the ASTUnit not to 412abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor/// contain any translation-unit information, false otherwise. 413754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorbool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 41428233428da1ebec20c893d6297ae3191318940ddDouglas Gregor delete SavedMainFileBuffer; 41528233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = 0; 41628233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 417abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!Invocation.get()) 418abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 419abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 420521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 421cb6dda1a7abe2fe30b0345bfbbf872cc73446678Daniel Dunbar CompilerInstance Clang; 422abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setInvocation(Invocation.take()); 423abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 424abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 4251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics that would 4261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // otherwise be dropped. 427abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setDiagnostics(&getDiagnostics()); 4281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 4291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor getDiagnostics(), 4301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 431abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setDiagnosticClient(getDiagnostics().getClient()); 4323687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 433521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 434521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 435521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTargetOpts())); 436a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor if (!Clang.hasTarget()) { 437a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor Clang.takeDiagnosticClient(); 438abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 439a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 440abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 441521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 442521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 443521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 444521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 445521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 446abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 447521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar assert(Clang.getFrontendOpts().Inputs.size() == 1 && 448521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 449c34ce3fa613d5e4a283e53615fceafd17390445bDaniel Dunbar assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 450521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 451faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 452faddc3e53a95c68f2c3a966e0f1e6eba110dafd6Daniel Dunbar "IR inputs not support here!"); 453521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 454abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Configure the various subsystems. 455abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // FIXME: Should we retain the previous file manager? 456abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor FileMgr.reset(new FileManager); 457abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor SourceMgr.reset(new SourceManager(getDiagnostics())); 458abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Ctx.reset(); 459abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PP.reset(); 460abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 461abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out old caches and data. 462abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor TopLevelDecls.clear(); 463abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor CleanTemporaryFiles(); 464abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PreprocessedEntitiesByFile.clear(); 465c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 466c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (!OverrideMainBuffer) 467c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.clear(); 4681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 469521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 470abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setFileManager(&getFileManager()); 471abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 472521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 473abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Clang.setSourceManager(&getSourceManager()); 474abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 475f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // If the main file has been overridden due to the use of a preamble, 476f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // make that override happen and introduce the preamble. 477f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOptions &PreprocessorOpts = Clang.getPreprocessorOpts(); 4781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor std::string PriorImplicitPCHInclude; 479f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (OverrideMainBuffer) { 480f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 481f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 482f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 483f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor = PreambleEndsAtStartOfLine; 4841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PriorImplicitPCHInclude = PreprocessorOpts.ImplicitPCHInclude; 485385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 486fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 48728233428da1ebec20c893d6297ae3191318940ddDouglas Gregor 48828233428da1ebec20c893d6297ae3191318940ddDouglas Gregor // Keep track of the override buffer; 48928233428da1ebec20c893d6297ae3191318940ddDouglas Gregor SavedMainFileBuffer = OverrideMainBuffer; 490c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 491c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // The stored diagnostic has the old source manager in it; update 492c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // the locations to refer into the new source manager. Since we've 493c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // been careful to make sure that the source manager's state 494c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // before and after are identical, so that we can reuse the source 495c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // location itself. 496c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor for (unsigned I = 0, N = StoredDiagnostics.size(); I != N; ++I) { 497c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), 498c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getSourceManager()); 499c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics[I].setLocation(Loc); 500c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor } 501f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor } 502f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 503abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<TopLevelDeclTrackerAction> Act; 504abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Act.reset(new TopLevelDeclTrackerAction(*this)); 505f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 506d3598a65716e120aef45aa2841d730e03f7101feDaniel Dunbar Clang.getFrontendOpts().Inputs[0].first)) 507521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 508abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 509f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->Execute(); 510abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 51164a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // Steal the created target, context, and preprocessor, and take back the 51264a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // source and file managers. 513abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Ctx.reset(Clang.takeASTContext()); 514abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor PP.reset(Clang.takePreprocessor()); 515521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 516521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 517abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Target.reset(Clang.takeTarget()); 518abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 519f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 520f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 521f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 5221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (OverrideMainBuffer) { 523f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 524f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 5251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 5261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 5271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 528521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnosticClient(); 529abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 530abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Invocation.reset(Clang.takeInvocation()); 531abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return false; 532abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 533521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 534f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor // Remove the overridden buffer we used for the preamble. 535fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor if (OverrideMainBuffer) { 536f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.eraseRemappedFile( 537f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreprocessorOpts.remapped_file_buffer_end() - 1); 538fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 5391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude; 540fae3b2f4743dad616623c4df2fdb0f5128bd36d9Douglas Gregor } 541f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor 542521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 543521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 544521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnosticClient(); 545abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Invocation.reset(Clang.takeInvocation()); 546abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 547abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 548abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 54944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor/// \brief Simple function to retrieve a path for a preamble precompiled header. 55044c181aec37789f25f6c15543c164416f72e562aDouglas Gregorstatic std::string GetPreamblePCHPath() { 55144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is lame; sys::Path should provide this function (in particular, 55244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // it should know how to find the temporary files dir). 55344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: This is really lame. I copied this code from the Driver! 55444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor std::string Error; 55544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor const char *TmpDir = ::getenv("TMPDIR"); 55644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 55744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TEMP"); 55844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 55944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = ::getenv("TMP"); 56044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!TmpDir) 56144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor TmpDir = "/tmp"; 56244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::Path P(TmpDir); 56344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor P.appendComponent("preamble"); 56444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (P.createTemporaryFileOnDisk()) 56544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return std::string(); 56644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 56744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor P.appendSuffix("pch"); 56844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor return P.str(); 56944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 57044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 571f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// \brief Compute the preamble for the main file, providing the source buffer 572f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that corresponds to the main file along with a pair (bytes, start-of-line) 573f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor/// that describes the preamble. 574f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregorstd::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 575df95a13ec73d2cdaea79555cb412d767f4963120Douglas GregorASTUnit::ComputePreamble(CompilerInvocation &Invocation, 576df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines, bool &CreatedBuffer) { 577175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 57844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOptions &PreprocessorOpts 579175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = Invocation.getPreprocessorOpts(); 580175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 581175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 58244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Try to determine if the main file has been remapped, either from the 58344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // command line (to another file) or directly through the compiler invocation 58444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // (to a memory buffer). 585175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::MemoryBuffer *Buffer = 0; 58644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 58744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 58844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-file remapping of the main file 58944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_iterator 590175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor M = PreprocessorOpts.remapped_file_begin(), 591175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor E = PreprocessorOpts.remapped_file_end(); 59244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 59344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 59444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 59544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 59644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 59744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. Try to load the resulting, remapped source. 598175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 59944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 600175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 601175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 602175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 60344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Buffer = llvm::MemoryBuffer::getFile(M->second); 60444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 605f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, 606f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::make_pair(0, true)); 607175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 60844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 609175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Remove this remapping. We've captured the buffer already. 61044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.eraseRemappedFile(M); 61144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_end(); 61244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 61344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 61444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 61544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 61644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Check whether there is a file-buffer remapping. It supercedes the 61744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // file-file remapping. 61844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 61944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.remapped_file_buffer_begin(), 62044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 62144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M != E; 62244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor ++M) { 62344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::sys::PathWithStatus MPath(M->first); 62444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 62544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (MainFileStatus->uniqueID == MStatus->uniqueID) { 62644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // We found a remapping. 627175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedBuffer) { 62844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor delete Buffer; 629175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = false; 630175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 63144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 632175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 633175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 634175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Remove this remapping. We've captured the buffer already. 63544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor M = PreprocessorOpts.eraseRemappedFile(M); 63644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor E = PreprocessorOpts.remapped_file_buffer_end(); 63744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 63844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 639175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 64044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 64144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 64244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // If the main source file was not remapped, load it now. 64344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) { 64444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Buffer = llvm::MemoryBuffer::getFile(FrontendOpts.Inputs[0].second); 64544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Buffer) 646f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 647175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 648175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CreatedBuffer = true; 649175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 650175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 651df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, MaxLines)); 652175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor} 653175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 654754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregorstatic llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 655754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor bool DeleteOld, 656754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor unsigned NewSize, 657754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::StringRef NewName) { 658754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *Result 659754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 660754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memcpy(const_cast<char*>(Result->getBufferStart()), 661754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor Old->getBufferStart(), Old->getBufferSize()); 662754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 663f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', NewSize - Old->getBufferSize() - 1); 664f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 665754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 666754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor if (DeleteOld) 667754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor delete Old; 668754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 669754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return Result; 670754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor} 671754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 672175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 673175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// the source file. 674175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 675175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// This routine will compute the preamble of the main source file. If a 676175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// non-trivial preamble is found, it will precompile that preamble into a 677175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// precompiled header so that the precompiled preamble can be used to reduce 678175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// reparsing time. If a precompiled preamble has already been constructed, 679175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// this routine will determine if it is still valid and, if so, avoid 680175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// rebuilding the precompiled preamble. 681175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor/// 682df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param AllowRebuild When true (the default), this routine is 683df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// allowed to rebuild the precompiled preamble if it is found to be 684df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// out-of-date. 685df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 686df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// \param MaxLines When non-zero, the maximum number of lines that 687df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// can occur within the preamble. 688df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor/// 689754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// \returns If the precompiled preamble can be used, returns a newly-allocated 690754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// buffer that should be used in place of the main file when doing so. 691754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor/// Otherwise, returns a NULL pointer. 692df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregorllvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 693df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool AllowRebuild, 694df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor unsigned MaxLines) { 695175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor CompilerInvocation PreambleInvocation(*Invocation); 696175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor FrontendOptions &FrontendOpts = PreambleInvocation.getFrontendOpts(); 697175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreprocessorOptions &PreprocessorOpts 698175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = PreambleInvocation.getPreprocessorOpts(); 699175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 700175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor bool CreatedPreambleBuffer = false; 701f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 702df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = ComputePreamble(PreambleInvocation, MaxLines, CreatedPreambleBuffer); 703175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 704f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (!NewPreamble.second.first) { 705175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We couldn't find a preamble in the main source. Clear out the current 706175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble, if we have one. It's obviously no good any more. 707175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 708175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!PreambleFile.empty()) { 709385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 710175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile.clear(); 711175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 712175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedPreambleBuffer) 713175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor delete NewPreamble.first; 714eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 715eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // The next time we actually see a preamble, precompile it. 716eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 717754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 71844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 71944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 720175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (!Preamble.empty()) { 721175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We've previously computed a preamble. Check whether we have the same 722175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble now that we did before, and that there's enough space in 723175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // the main-file buffer within the precompiled preamble to fit the 724175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // new main file. 725f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor if (Preamble.size() == NewPreamble.second.first && 726f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleEndsAtStartOfLine == NewPreamble.second.second && 727592508ed997e52207cf380f9b6eb9943994ad7aeDouglas Gregor NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 728175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memcmp(&Preamble[0], NewPreamble.first->getBufferStart(), 729f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor NewPreamble.second.first) == 0) { 730175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // The preamble has not changed. We may be able to re-use the precompiled 731175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // preamble. 732c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 733cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check that none of the files used by the preamble have changed. 734cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor bool AnyFileChanged = false; 735cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 736cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // First, make a record of those files that have been overridden via 737cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remapping or unsaved_files. 738cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 739cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_iterator 740cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_begin(), 741cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_end(); 742cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 743cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 744cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 745cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (stat(R->second.c_str(), &StatBuf)) { 746cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file we're remapping to, assume that something 747cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // horrible happened. 748cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 749cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor break; 750cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 751754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor 752cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 753cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime); 754cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 755cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (PreprocessorOptions::remapped_file_buffer_iterator 756cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor R = PreprocessorOpts.remapped_file_buffer_begin(), 757cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor REnd = PreprocessorOpts.remapped_file_buffer_end(); 758cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && R != REnd; 759cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++R) { 760cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // FIXME: Should we actually compare the contents of file->buffer 761cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // remappings? 762cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 763cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 0); 764cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 765cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 766cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Check whether anything has changed. 767cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 768cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 769cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor !AnyFileChanged && F != FEnd; 770cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 771cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 772cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = OverriddenFiles.find(F->first()); 773cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden != OverriddenFiles.end()) { 774cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // This file was remapped; check whether the newly-mapped file 775cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // matches up with the previous mapping. 776cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (Overridden->second != F->second) 777cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 778cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 779cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 780cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 781cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // The file was not remapped; check whether it has changed on disk. 782cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor struct stat StatBuf; 783cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (stat(F->first(), &StatBuf)) { 784cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // If we can't stat the file, assume that something horrible happened. 785cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 786cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } else if (StatBuf.st_size != F->second.first || 787cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor StatBuf.st_mtime != F->second.second) 788cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor AnyFileChanged = true; 789cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 790cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 791cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!AnyFileChanged) { 792c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Okay! We can re-use the precompiled preamble. 793c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 794c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Set the state of the diagnostic object to mimic its state 795c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // after parsing the preamble. 796c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 797c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().setNumWarnings(NumWarningsInPreamble); 798c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (StoredDiagnostics.size() > NumStoredDiagnosticsInPreamble) 799c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.erase( 800c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.begin() + NumStoredDiagnosticsInPreamble, 801c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor StoredDiagnostics.end()); 802c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 803c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Create a version of the main file buffer that is padded to 804c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // buffer size we reserved when creating the preamble. 805cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 806cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor CreatedPreambleBuffer, 807cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor PreambleReservedSize, 808cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FrontendOpts.Inputs[0].second); 809cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 810175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 811df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 812df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we aren't allowed to rebuild the precompiled preamble, just 813df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 814df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!AllowRebuild) 815df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 816175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 817175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We can't reuse the previously-computed preamble. Build a new one. 818175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 819385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::sys::Path(PreambleFile).eraseFromDisk(); 820eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 821df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } else if (!AllowRebuild) { 822df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // We aren't allowed to rebuild the precompiled preamble; just 823df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // return now. 824df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor return 0; 825df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 826eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 827eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If the preamble rebuild counter > 1, it's because we previously 828eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // failed to build a preamble and we're not yet ready to try 829eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // again. Decrement the counter and return a failure. 830eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PreambleRebuildCounter > 1) { 831eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor --PreambleRebuildCounter; 832eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor return 0; 833eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 834eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor 835175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // We did not previously compute a preamble, or it can't be reused anyway. 836385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::Timer *PreambleTimer = 0; 837385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (TimerGroup.get()) { 838385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer = new llvm::Timer("Precompiling preamble", *TimerGroup); 839385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer->startTimer(); 840385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor Timers.push_back(PreambleTimer); 841385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor } 84244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 84344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a new buffer that stores the preamble. The buffer also contains 84444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // extra space for the original contents of the file (which will be present 84544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // when we actually parse the file) along with more room in case the file 846175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // grows. 847175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize = NewPreamble.first->getBufferSize(); 848175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (PreambleReservedSize < 4096) 849f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor PreambleReservedSize = 8191; 85044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor else 851175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleReservedSize *= 2; 852175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 853c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // Save the preamble text for later; we'll need to compare against it for 854c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor // subsequent reparses. 855c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor Preamble.assign(NewPreamble.first->getBufferStart(), 856c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NewPreamble.first->getBufferStart() 857c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor + NewPreamble.second.first); 858c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor PreambleEndsAtStartOfLine = NewPreamble.second.second; 859c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor 86044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor llvm::MemoryBuffer *PreambleBuffer 861175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 86244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.Inputs[0].second); 86344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 864175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor NewPreamble.first->getBufferStart(), Preamble.size()); 865175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 866f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor ' ', PreambleReservedSize - Preamble.size() - 1); 867f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 86844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 86944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Remap the main source file to the preamble buffer. 870175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].second); 87144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 87244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 87344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Tell the compiler invocation to generate a temporary precompiled header. 87444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor FrontendOpts.ProgramAction = frontend::GeneratePCH; 875f65339e0f1b9ccfc0c92c85f68bb2e72ea48a27bSebastian Redl // FIXME: Set ChainedPCH unconditionally, once it is ready. 876f65339e0f1b9ccfc0c92c85f68bb2e72ea48a27bSebastian Redl if (::getenv("LIBCLANG_CHAINING")) 877f65339e0f1b9ccfc0c92c85f68bb2e72ea48a27bSebastian Redl FrontendOpts.ChainedPCH = true; 87844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: Generate the precompiled header into memory? 879385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor FrontendOpts.OutputFile = GetPreamblePCHPath(); 88044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 88144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the compiler instance to use for building the precompiled preamble. 88244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor CompilerInstance Clang; 88344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setInvocation(&PreambleInvocation); 88444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 88544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 8861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing all of the diagnostics produced. 88744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setDiagnostics(&getDiagnostics()); 8881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(CaptureDiagnostics, 8891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor getDiagnostics(), 8901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 89144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setDiagnosticClient(getDiagnostics().getClient()); 89244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 89344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the target instance. 89444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 89544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getTargetOpts())); 89644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Clang.hasTarget()) { 89744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeDiagnosticClient(); 898175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 899175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 900175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedPreambleBuffer) 901175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor delete NewPreamble.first; 902385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (PreambleTimer) 903385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer->stopTimer(); 904eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 905754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 90644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 90744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 90844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Inform the target of the language options. 90944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // 91044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 91144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // created. This complexity should be lifted elsewhere. 91244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 91344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 91444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs.size() == 1 && 91544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "Invocation must have exactly one source file!"); 91644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 91744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "FIXME: AST inputs not yet supported here!"); 91844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 91944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor "IR inputs not support here!"); 92044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 92144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Clear out old caches and data. 92244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor StoredDiagnostics.clear(); 923eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.clear(); 924eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 92544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 92644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create a file manager object to provide access to and cache the filesystem. 92744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setFileManager(new FileManager); 92844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 92944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Create the source manager. 93044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.setSourceManager(new SourceManager(getDiagnostics())); 93144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 9321d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor llvm::OwningPtr<PrecompilePreambleAction> Act; 9331d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor Act.reset(new PrecompilePreambleAction(*this)); 93444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 93544c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.getFrontendOpts().Inputs[0].first)) { 93644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeDiagnosticClient(); 93744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeInvocation(); 938175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 939175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 940175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedPreambleBuffer) 941175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor delete NewPreamble.first; 942385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (PreambleTimer) 943385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer->stopTimer(); 944eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 945385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 946754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 94744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 94844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 94944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->Execute(); 95044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Act->EndSourceFile(); 95144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeDiagnosticClient(); 95244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor Clang.takeInvocation(); 95344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 954eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Diagnostics->hasErrorOccurred()) { 955175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // There were errors parsing the preamble, so no precompiled header was 956175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // generated. Forget that we even tried. 957175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // FIXME: Should we leave a note for ourselves to try again? 958175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 959175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor Preamble.clear(); 960175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor if (CreatedPreambleBuffer) 961175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor delete NewPreamble.first; 962385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (PreambleTimer) 963385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer->stopTimer(); 964eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 965eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = DefaultPreambleRebuildInterval; 966754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return 0; 967175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor } 968175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 969175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Keep track of the preamble we precompiled. 970175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor PreambleFile = FrontendOpts.OutputFile; 971c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumStoredDiagnosticsInPreamble = StoredDiagnostics.size(); 972c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 973cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 974cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Keep track of all of the files that the source manager knows about, 975cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // so we can verify whether they have changed or not. 976cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble.clear(); 977cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor SourceManager &SourceMgr = Clang.getSourceManager(); 978cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const llvm::MemoryBuffer *MainFileBuffer 979cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 980cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 981cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FEnd = SourceMgr.fileinfo_end(); 982cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor F != FEnd; 983cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor ++F) { 984cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor const FileEntry *File = F->second->Entry; 985cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor if (!File || F->second->getRawBuffer() == MainFileBuffer) 986cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor continue; 987cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 988cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor FilesInPreamble[File->getName()] 989cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor = std::make_pair(F->second->getSize(), File->getModificationTime()); 990cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor } 991cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 992385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (PreambleTimer) 993385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor PreambleTimer->stopTimer(); 994385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 995eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor PreambleRebuildCounter = 1; 996754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor return CreatePaddedMainFileBuffer(NewPreamble.first, 997754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor CreatedPreambleBuffer, 998754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor PreambleReservedSize, 999754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor FrontendOpts.Inputs[0].second); 100044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor} 1001abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1002eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorvoid ASTUnit::RealizeTopLevelDeclsFromPreamble() { 1003eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor std::vector<Decl *> Resolved; 1004eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.reserve(TopLevelDeclsInPreamble.size()); 1005eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ExternalASTSource &Source = *getASTContext().getExternalSource(); 1006eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 1007eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // Resolve the declaration ID to an actual declaration, possibly 1008eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor // deserializing the declaration in the process. 1009eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 1010eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (D) 1011eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor Resolved.push_back(D); 1012eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor } 1013eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDeclsInPreamble.clear(); 1014eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 1015eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1016eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1017eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorunsigned ASTUnit::getMaxPCHLevel() const { 1018eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (!getOnlyLocalDecls()) 1019eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor return Decl::MaxPCHLevel; 1020eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1021eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor unsigned Result = 0; 1022eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (isMainFileAST() || SavedMainFileBuffer) 1023eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor ++Result; 1024eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor return Result; 1025eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor} 1026eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor 1027abc563f554951259bbe0315055cad92ee14d87e4Douglas GregorASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 1028abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1029abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor bool OnlyLocalDecls, 103044c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1031df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1032df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool CompleteTranslationUnit) { 1033abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!Diags.getPtr()) { 1034abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 1035abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // with the default options. 1036abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor DiagnosticOptions DiagOpts; 1037abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 1038abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 1039abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1040abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Create the AST unit. 1041abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::OwningPtr<ASTUnit> AST; 1042abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST.reset(new ASTUnit(false)); 1043abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Diagnostics = Diags; 1044abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->CaptureDiagnostics = CaptureDiagnostics; 1045abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 1046df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor AST->CompleteTranslationUnit = CompleteTranslationUnit; 1047abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor AST->Invocation.reset(CI); 1048f4f6c9db68465b886ec2e596feaa6ecc782395a4Douglas Gregor CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 1049abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1050385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (getenv("LIBCLANG_TIMING")) 1051385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor AST->TimerGroup.reset( 1052385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor new llvm::TimerGroup(CI->getFrontendOpts().Inputs[0].second)); 1053385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1054385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1055754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1056fd0b87006b478bb573d369385aed64a58225264dDouglas Gregor // FIXME: When C++ PCH is ready, allow use of it for a precompiled preamble. 1057eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (PrecompilePreamble && !CI->getLangOpts().CPlusPlus) { 1058eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor AST->PreambleRebuildCounter = 1; 1059df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor OverrideMainBuffer = AST->getMainBufferWithPrecompiledPreamble(); 1060eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor } 106144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 1062385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::Timer *ParsingTimer = 0; 1063385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (AST->TimerGroup.get()) { 1064385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ParsingTimer = new llvm::Timer("Initial parse", *AST->TimerGroup); 1065385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ParsingTimer->startTimer(); 1066385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor AST->Timers.push_back(ParsingTimer); 1067385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor } 1068abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1069385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor bool Failed = AST->Parse(OverrideMainBuffer); 1070385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (ParsingTimer) 1071385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ParsingTimer->stopTimer(); 1072385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1073385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor return Failed? 0 : AST.take(); 1074521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 10757b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 10767b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 10777b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 107828019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 1079869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar llvm::StringRef ResourceFilesPath, 10807b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 10814db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1082a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor unsigned NumRemappedFiles, 108344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool CaptureDiagnostics, 1084df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool PrecompilePreamble, 1085df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool CompleteTranslationUnit) { 108628019772db70d4547be05a042eb950bc910f134fDouglas Gregor if (!Diags.getPtr()) { 10873687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // No diagnostics engine was provided, so create our own diagnostics object 10883687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor // with the default options. 10893687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor DiagnosticOptions DiagOpts; 109028019772db70d4547be05a042eb950bc910f134fDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 10913687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor } 10923687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor 10937b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::SmallVector<const char *, 16> Args; 10947b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("<clang>"); // FIXME: Remove dummy argument. 10957b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.insert(Args.end(), ArgBegin, ArgEnd); 10967b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 10977b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // FIXME: Find a cleaner way to force the driver into restricted modes. We 10987b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // also want to force it to use clang. 10997b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("-fsyntax-only"); 11007b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 1101869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar // FIXME: We shouldn't have to pass in the path info. 11020bbad519aa068206f1e158d5073f72a39fbe83c5Daniel Dunbar driver::Driver TheDriver("clang", llvm::sys::getHostTriple(), 11033687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor "a.out", false, false, *Diags); 11043bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar 11053bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar // Don't check that inputs exist, they have been remapped. 11063bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar TheDriver.setCheckInputsExist(false); 11073bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar 11087b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::OwningPtr<driver::Compilation> C( 11097b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar TheDriver.BuildCompilation(Args.size(), Args.data())); 11107b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 11117b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // We expect to get back exactly one command job, if we didn't something 11127b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // failed. 11137b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::JobList &Jobs = C->getJobs(); 11147b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) { 11157b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::SmallString<256> Msg; 11167b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::raw_svector_ostream OS(Msg); 11177b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar C->PrintJob(OS, C->getJobs(), "; ", true); 11183687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); 11197b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar return 0; 11207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 11217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 11227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 11237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { 11243687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor Diags->Report(diag::err_fe_expected_clang_command); 11257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar return 0; 11267b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 11277b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 11287b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::ArgStringList &CCArgs = Cmd->getArguments(); 1129807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation); 1130cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman CompilerInvocation::CreateFromArgs(*CI, 1131cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman const_cast<const char **>(CCArgs.data()), 1132cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman const_cast<const char **>(CCArgs.data()) + 113344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor CCArgs.size(), 11343687e9d3a5dbfa9963af02a49a2b139d91310813Douglas Gregor *Diags); 11351e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar 11364db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 11374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 1138807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1139b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar RemappedFiles[I].second); 11404db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 11418b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 1142807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 11437b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 1144b26d483a9f7fdc815e87bbbac4af916307b4c07dDaniel Dunbar CI->getFrontendOpts().DisableFree = true; 1145a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls, 1146df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CaptureDiagnostics, PrecompilePreamble, 1147df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CompleteTranslationUnit); 11487b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 1149abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1150abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregorbool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 1151abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!Invocation.get()) 1152abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor return true; 1153abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1154385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor llvm::Timer *ReparsingTimer = 0; 1155385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (TimerGroup.get()) { 1156385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ReparsingTimer = new llvm::Timer("Reparse", *TimerGroup); 1157385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ReparsingTimer->startTimer(); 1158385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor Timers.push_back(ReparsingTimer); 1159385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor } 1160385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor 1161cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor // Remap files. 1162cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().clearRemappedFiles(); 1163cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 1164cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 1165cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor RemappedFiles[I].second); 1166cc5888d833caf90ebda37f24da40d2cd06b4d820Douglas Gregor 1167eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // If we have a preamble file lying around, or if we might try to 1168eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor // build a precompiled preamble, do so now. 1169754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1170eababfbddb74d186f78783a9731a78ad371c9800Douglas Gregor if (!PreambleFile.empty() || PreambleRebuildCounter > 0) 1171df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(); 1172175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor 1173abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor // Clear out the diagnostics state. 1174c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor if (!OverrideMainBuffer) 1175c0659ec614c428c7d15746fcad15d50a2703751dDouglas Gregor getDiagnostics().Reset(); 1176abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 1177175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor // Parse the sources 1178754f3490c5b0f5d83361f001bc87944f23644abbDouglas Gregor bool Result = Parse(OverrideMainBuffer); 1179385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor if (ReparsingTimer) 1180385103b79c5338a2be5da0ca70652400bc267371Douglas Gregor ReparsingTimer->stopTimer(); 1181175c4a9aa61f4449f27b729737e4438684ac6d92Douglas Gregor return Result; 1182abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 11831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 11841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregorvoid ASTUnit::CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, 11851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFile *RemappedFiles, 11861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor unsigned NumRemappedFiles, 1187cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeMacros, 1188cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor bool IncludeCodePatterns, 11891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CodeCompleteConsumer &Consumer, 11901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Diagnostic &Diag, LangOptions &LangOpts, 11911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor SourceManager &SourceMgr, FileManager &FileMgr, 11921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics) { 11931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (!Invocation.get()) 11941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor return; 11951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1196df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::Timer *CompletionTimer = 0; 1197df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (TimerGroup.get()) { 1198df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::SmallString<128> TimerName; 1199df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::raw_svector_ostream TimerNameOut(TimerName); 1200df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor TimerNameOut << "Code completion @ " << File << ":" << Line << ":" 1201df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor << Column; 1202df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CompletionTimer = new llvm::Timer(TimerNameOut.str(), *TimerGroup); 1203df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CompletionTimer->startTimer(); 1204df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor Timers.push_back(CompletionTimer); 1205df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1206df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 12071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CompilerInvocation CCInvocation(*Invocation); 12081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOptions &FrontendOpts = CCInvocation.getFrontendOpts(); 12091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOptions &PreprocessorOpts = CCInvocation.getPreprocessorOpts(); 1210cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 1211cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor FrontendOpts.ShowMacrosInCodeCompletion = IncludeMacros; 1212cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns; 12131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.FileName = File; 12141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Line = Line; 12151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor FrontendOpts.CodeCompletionAt.Column = Column; 12161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1217cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor // Turn on spell-checking when performing code completion. It leads 1218cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor // to better results. 1219cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor unsigned SpellChecking = CCInvocation.getLangOpts().SpellChecking; 1220cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor CCInvocation.getLangOpts().SpellChecking = 1; 1221cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor 12221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set the language options appropriately. 12231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor LangOpts = CCInvocation.getLangOpts(); 12241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CompilerInstance Clang; 12261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setInvocation(&CCInvocation); 12271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 12281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Set up diagnostics, capturing any diagnostics produced. 12301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setDiagnostics(&Diag); 12311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor CaptureDroppedDiagnostics Capture(true, 12321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getDiagnostics(), 12331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor StoredDiagnostics); 12341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setDiagnosticClient(Diag.getClient()); 12351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Create the target instance. 12371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 12381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getTargetOpts())); 12391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (!Clang.hasTarget()) { 12401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeDiagnosticClient(); 12411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeInvocation(); 12421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 12431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Inform the target of the language options. 12451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // 12461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // FIXME: We shouldn't need to do this, the target should be immutable once 12471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // created. This complexity should be lifted elsewhere. 12481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 12491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs.size() == 1 && 12511abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "Invocation must have exactly one source file!"); 12521abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_AST && 12531abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "FIXME: AST inputs not yet supported here!"); 12541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor assert(Clang.getFrontendOpts().Inputs[0].first != IK_LLVM_IR && 12551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor "IR inputs not support here!"); 12561abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12571abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12581abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the source and file managers that we were given. 12591abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setFileManager(&FileMgr); 12601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setSourceManager(&SourceMgr); 12611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12621abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Remap files. 12631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.clearRemappedFiles(); 1264b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor PreprocessorOpts.RetainRemappedFileBuffers = true; 12651abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 12661abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, 12671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor RemappedFiles[I].second); 12681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 12691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Use the code completion consumer we were given. 12701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.setCodeCompletionConsumer(&Consumer); 12711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 1272df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If we have a precompiled preamble, try to use it. We only allow 1273df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // the use of the precompiled preamble if we're if the completion 1274df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // point is within the main file, after the end of the precompiled 1275df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // preamble. 1276df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::MemoryBuffer *OverrideMainBuffer = 0; 1277df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (!PreambleFile.empty()) { 1278df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor using llvm::sys::FileStatus; 1279df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus CompleteFilePath(File); 1280df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor llvm::sys::PathWithStatus MainPath(OriginalSourceFile); 1281df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus()) 1282df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (const FileStatus *MainStatus = MainPath.getFileStatus()) 1283df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID()) 1284df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(false, 1285df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor Line); 1286df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1287df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1288df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // If the main file has been overridden due to the use of a preamble, 1289df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // make that override happen and introduce the preamble. 1290df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (OverrideMainBuffer) { 1291df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 1292df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 1293df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.PrecompiledPreambleBytes.second 1294df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = PreambleEndsAtStartOfLine; 1295df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.ImplicitPCHInclude = PreambleFile; 1296df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor PreprocessorOpts.DisablePCHValidation = true; 1297df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1298df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // The stored diagnostics have the old source manager. Copy them 1299df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // to our output set of stored diagnostics, updating the source 1300df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor // manager to the one we were given. 1301df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor for (unsigned I = 0, N = this->StoredDiagnostics.size(); I != N; ++I) { 1302df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor StoredDiagnostics.push_back(this->StoredDiagnostics[I]); 1303df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SourceMgr); 1304df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor StoredDiagnostics[I].setLocation(Loc); 1305df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1306df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor } 1307df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 13081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor llvm::OwningPtr<SyntaxOnlyAction> Act; 13091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act.reset(new SyntaxOnlyAction); 13101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor if (Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 13111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.getFrontendOpts().Inputs[0].first)) { 13121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->Execute(); 13131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Act->EndSourceFile(); 13141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor } 1315df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 1316df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor if (CompletionTimer) 1317df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor CompletionTimer->stopTimer(); 13181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor 13191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor // Steal back our resources. 1320df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor delete OverrideMainBuffer; 13211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeFileManager(); 13221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeSourceManager(); 13231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeInvocation(); 13241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeDiagnosticClient(); 13251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor Clang.takeCodeCompletionConsumer(); 1326cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor CCInvocation.getLangOpts().SpellChecking = SpellChecking; 13271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} 1328