ASTUnit.cpp revision f7acc37450d59ef751df73acb91de73850cc6517
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" 150853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Frontend/PCHReader.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" 280853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 290853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 30d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar#include "clang/Basic/TargetOptions.h" 310853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 334db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 347b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar#include "llvm/System/Host.h" 354a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer#include "llvm/System/Path.h" 360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisusing namespace clang; 370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 385262fda30b876c8aae95f2eb92e349418d6b14bbDaniel DunbarASTUnit::ASTUnit(bool _MainFileIsAST) 395262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar : tempFile(false), MainFileIsAST(_MainFileIsAST) { 4036c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff} 41521bf9c529e653ab28896d027352d3e16e2672d5Daniel DunbarASTUnit::~ASTUnit() { 42e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff if (tempFile) 434a630d30cd8ee9c8f46b8d3c9ad7e7e00d393f32Benjamin Kramer llvm::sys::Path(getPCHFileName()).eraseFromDisk(); 44e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 450853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 460853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidisnamespace { 470853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 480853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// \brief Gathers information from PCHReader that will be used to initialize 490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis/// a Preprocessor. 50bd21828179a61bd0954b082825cfb8a93345f602Benjamin Kramerclass PCHInfoCollector : public PCHReaderListener { 510853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions &LangOpt; 520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HSI; 530853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple; 540853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &Predefines; 550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter; 561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 570853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned NumHeaderInfos; 581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 590853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidispublic: 600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 610853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &TargetTriple, std::string &Predefines, 620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned &Counter) 630853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 640853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 660853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 670853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOpt = LangOpts; 680853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 690853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar virtual bool ReadTargetTriple(llvm::StringRef Triple) { 720853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis TargetTriple = Triple; 730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 76dc3c0d20375bda7775b2fade05b20e315798b9feDaniel Dunbar virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef, 770853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis FileID PCHBufferID, 787b5a1210d93ca62ecd61800f245c87259b1f8f79Daniel Dunbar llvm::StringRef OriginalFileName, 790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string &SuggestedPredefines) { 800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Predefines = PCHPredef; 810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return false; 820853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) { 850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis virtual void ReadCounter(unsigned Value) { 890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Counter = Value; 900853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 910853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis}; 920853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} // anonymous namespace 940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 9577accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroffconst std::string &ASTUnit::getOriginalSourceFileName() { 9668d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar return OriginalSourceFile; 9777accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff} 980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 99e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroffconst std::string &ASTUnit::getPCHFileName() { 100c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar assert(isMainFileAST() && "Not an ASTUnit from a PCH file!"); 1017297c18c843138625a61e01a137664a176739683Benjamin Kramer return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName(); 102e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff} 103e19944c93961b7618f4f3f3185f698f46369ea54Steve Naroff 1040853a02c3b04d96a3c432b883e403175c954cd81Argyrios KyrtzidisASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, 1055262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar Diagnostic &Diags, 1065cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek bool OnlyLocalDecls, 1074db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor bool UseBumpAllocator, 1084db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 1094db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor unsigned NumRemappedFiles) { 1105262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true)); 1117d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor AST->OnlyLocalDecls = OnlyLocalDecls; 11236c4464ba6cfc2a63dc67c493ef2f5ab2aea09ccSteve Naroff AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 1130853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1144db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) { 1154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Create the file entry for the file that we're mapping from. 1164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor const FileEntry *FromFile 1174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 1184db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second->getBufferSize(), 1194db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 0); 1204db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor if (!FromFile) { 1214db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor Diags.Report(diag::err_fe_remap_missing_from_file) 1224db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor << RemappedFiles[I].first; 1234db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor continue; 1244db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 1254db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 1264db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override the contents of the "from" file with the contents of 1274db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // the "to" file. 1284db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor AST->getSourceManager().overrideFileContents(FromFile, 1294db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second); 1304db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 1314db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 1320853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Gather Info for preprocessor construction later on. 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1340853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis LangOptions LangInfo; 1350853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 1360853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string TargetTriple; 1370853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis std::string Predefines; 1380853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis unsigned Counter; 1390853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 140bce6f62ae7d2c15992617f64e30067803fb5b47fDaniel Dunbar llvm::OwningPtr<PCHReader> Reader; 1410853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis llvm::OwningPtr<ExternalASTSource> Source; 1420853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 143fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), 1445262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar Diags)); 145cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, 146cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Predefines, Counter)); 147cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar 148cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar switch (Reader->ReadPCH(Filename)) { 1490853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis case PCHReader::Success: 1500853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis break; 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1520853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis case PCHReader::Failure: 153106c9981f18084e60602244f1feaeabbbe8ab5e8Argyrios Kyrtzidis case PCHReader::IgnorePCH: 1545262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar Diags.Report(diag::err_fe_unable_to_load_pch); 1550853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis return NULL; 1560853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis } 1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 15968d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 1600853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // PCH loaded successfully. Now create the preprocessor. 1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1620853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Get information about the target being compiled for. 163d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // 164d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar // FIXME: This is broken, we should store the TargetOptions in the PCH. 165d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOptions TargetOpts; 166d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.ABI = ""; 167d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.CPU = ""; 168d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Features.clear(); 169d58c03f42ebb4e548c2b53fa25b1cfe02ebb9ac0Daniel Dunbar TargetOpts.Triple = TargetTriple; 1705262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar AST->Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts)); 1715262fda30b876c8aae95f2eb92e349418d6b14bbDaniel Dunbar AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(), 17231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), HeaderInfo)); 1730853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Preprocessor &PP = *AST->PP.get(); 1740853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 175d5b6126389e1e2fd89e498fe17da4bb44ece0302Daniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 1760853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.setCounterValue(Counter); 177cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->setPreprocessor(PP); 1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1790853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Create and initialize the ASTContext. 1800853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1810853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis AST->Ctx.reset(new ASTContext(LangInfo, 18231b87d8006d4863dd9b17e515ac720941efc38e3Daniel Dunbar AST->getSourceManager(), 1830853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis *AST->Target.get(), 1840853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getIdentifierTable(), 1850853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getSelectorTable(), 1860853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis PP.getBuiltinInfo(), 1875cf48766d626ff6b223acc9d4b7e415ca8480836Ted Kremenek /* FreeMemory = */ !UseBumpAllocator, 1880853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis /* size_reserve = */0)); 1890853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis ASTContext &Context = *AST->Ctx.get(); 1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 191cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Reader->InitializeContext(Context); 1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1930853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // Attach the PCH reader to the AST context as an external AST 1940853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // source, so that declarations will be deserialized from the 1950853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis // PCH file as needed. 196cc318939daaa50fc07f7d431caec3c8679893e9cDaniel Dunbar Source.reset(Reader.take()); 1970853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis Context.setExternalSource(Source); 1980853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis 1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return AST.take(); 2000853a02c3b04d96a3c432b883e403175c954cd81Argyrios Kyrtzidis} 201521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 202521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarnamespace { 203521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 204f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerConsumer : public ASTConsumer { 205f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 206f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 207f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 208f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {} 209f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 210f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar void HandleTopLevelDecl(DeclGroupRef D) { 211f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) 212f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Unit.getTopLevelDecls().push_back(*it); 213f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar } 214f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar}; 215f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 216f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarclass TopLevelDeclTrackerAction : public ASTFrontendAction { 217f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbarpublic: 218f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar ASTUnit &Unit; 219f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 220521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 221521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar llvm::StringRef InFile) { 222f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar return new TopLevelDeclTrackerConsumer(Unit); 223521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar } 224521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 225521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarpublic: 226f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 227f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar 228521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar virtual bool hasCodeCompletionSupport() const { return false; } 229521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar}; 230521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 231521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 232521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 233f7acc37450d59ef751df73acb91de73850cc6517Daniel DunbarASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 234521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Diagnostic &Diags, 23568ea2ac7fd98a5a44c7a5b04c54076cf794531cbDaniel Dunbar bool OnlyLocalDecls) { 236521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the compiler instance to use for building the AST. 237cb6dda1a7abe2fe30b0345bfbbf872cc73446678Daniel Dunbar CompilerInstance Clang; 238521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar llvm::OwningPtr<ASTUnit> AST; 239f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar llvm::OwningPtr<TopLevelDeclTrackerAction> Act; 240521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 241f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar Clang.setInvocation(CI); 242521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 243521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setDiagnostics(&Diags); 244521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setDiagnosticClient(Diags.getClient()); 245521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 246521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the target instance. 247521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), 248521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTargetOpts())); 249521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar if (!Clang.hasTarget()) 250521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 251521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 252521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Inform the target of the language options. 253521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // 254521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 255521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // created. This complexity should be lifted elsewhere. 256521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); 257521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 258521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar assert(Clang.getFrontendOpts().Inputs.size() == 1 && 259521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "Invocation must have exactly one source file!"); 260521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST && 261521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar "FIXME: AST inputs not yet supported here!"); 262521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 263521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the AST unit. 264c7822dbf3c01a2a5f837cff82ba7889ea755dacaDaniel Dunbar AST.reset(new ASTUnit(false)); 265521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 26668ea2ac7fd98a5a44c7a5b04c54076cf794531cbDaniel Dunbar AST->OnlyLocalDecls = OnlyLocalDecls; 26768d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second; 26868d40e2d16b9fadba386853d6bbb60089291fdc5Daniel Dunbar 269521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create a file manager object to provide access to and cache the filesystem. 270521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setFileManager(&AST->getFileManager()); 271521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 272521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the source manager. 273521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.setSourceManager(&AST->getSourceManager()); 274521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 275521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar // Create the preprocessor. 276521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.createPreprocessor(); 277521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 278f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act.reset(new TopLevelDeclTrackerAction(*AST)); 279f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, 280521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar /*IsAST=*/false)) 281521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar goto error; 282521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 283f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->Execute(); 284521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 28564a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // Steal the created target, context, and preprocessor, and take back the 28664a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar // source and file managers. 287521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar AST->Ctx.reset(Clang.takeASTContext()); 288521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar AST->PP.reset(Clang.takePreprocessor()); 289521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 290521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 29164a32baec6fdc7e5fbcba417a2754f78ab876245Daniel Dunbar AST->Target.reset(Clang.takeTarget()); 292521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 293f772d1e2a5688572d07f42896a50ac57a4a41fe8Daniel Dunbar Act->EndSourceFile(); 294521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 295521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnosticClient(); 296521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnostics(); 297807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar Clang.takeInvocation(); 298521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 299f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar AST->Invocation.reset(Clang.takeInvocation()); 300521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar return AST.take(); 301521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar 302521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbarerror: 303521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeSourceManager(); 304521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeFileManager(); 305521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnosticClient(); 306521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar Clang.takeDiagnostics(); 307521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar return 0; 308521bf9c529e653ab28896d027352d3e16e2672d5Daniel Dunbar} 3097b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 3107b55668db7618334cc40011d3c1e128524d89462Daniel DunbarASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 3117b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const char **ArgEnd, 3127b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Diagnostic &Diags, 313869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar llvm::StringRef ResourceFilesPath, 3147b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar bool OnlyLocalDecls, 3154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor bool UseBumpAllocator, 3164db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFile *RemappedFiles, 3174db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor unsigned NumRemappedFiles) { 3187b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::SmallVector<const char *, 16> Args; 3197b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("<clang>"); // FIXME: Remove dummy argument. 3207b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.insert(Args.end(), ArgBegin, ArgEnd); 3217b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 3227b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // FIXME: Find a cleaner way to force the driver into restricted modes. We 3237b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // also want to force it to use clang. 3247b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Args.push_back("-fsyntax-only"); 3257b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 326869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar // FIXME: We shouldn't have to pass in the path info. 327869824e87940f97b87064db2df2861e82e08a8c6Daniel Dunbar driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(), 3287b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar "a.out", false, Diags); 3293bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar 3303bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar // Don't check that inputs exist, they have been remapped. 3313bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar TheDriver.setCheckInputsExist(false); 3323bd54cc56276c386f4d50940a9fbfcad7a69cb75Daniel Dunbar 3337b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::OwningPtr<driver::Compilation> C( 3347b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar TheDriver.BuildCompilation(Args.size(), Args.data())); 3357b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 3367b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // We expect to get back exactly one command job, if we didn't something 3377b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar // failed. 3387b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::JobList &Jobs = C->getJobs(); 3397b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (Jobs.size() != 1 || !isa<driver::Command>(Jobs.begin())) { 3407b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::SmallString<256> Msg; 3417b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar llvm::raw_svector_ostream OS(Msg); 3427b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar C->PrintJob(OS, C->getJobs(), "; ", true); 3437b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Diags.Report(diag::err_fe_expected_compiler_job) << OS.str(); 3447b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar return 0; 3457b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 3467b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 3477b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin()); 3487b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") { 3497b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar Diags.Report(diag::err_fe_expected_clang_command); 3507b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar return 0; 3517b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar } 3527b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 3537b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar const driver::ArgStringList &CCArgs = Cmd->getArguments(); 354807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation); 355807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(), 3567b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar (const char**) CCArgs.data()+CCArgs.size(), 3571e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar Diags); 3581e69fe3a9f0a42b32a3000bda51677d51416564eDaniel Dunbar 3594db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor // Override any files that need remapping 3604db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != NumRemappedFiles; ++I) 361807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 3624db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles[I].second); 3634db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor 3648b9adfea5e834eaee0f45d8cc7fb052d68df4a46Daniel Dunbar // Override the resources path. 365807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 3667b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar 367807b06157a1a5c050520fc194d32f16d22d423a8Daniel Dunbar CI->getFrontendOpts().DisableFree = UseBumpAllocator; 368f7acc37450d59ef751df73acb91de73850cc6517Daniel Dunbar return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls); 3697b55668db7618334cc40011d3c1e128524d89462Daniel Dunbar} 370