ASTUnit.cpp revision 198398
1//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// ASTUnit Implementation. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Frontend/ASTUnit.h" 15#include "clang/Frontend/PCHReader.h" 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/DeclVisitor.h" 18#include "clang/AST/StmtVisitor.h" 19#include "clang/Lex/HeaderSearch.h" 20#include "clang/Lex/Preprocessor.h" 21#include "clang/Basic/TargetInfo.h" 22#include "clang/Basic/Diagnostic.h" 23#include "llvm/Support/Compiler.h" 24#include "llvm/System/Path.h" 25 26using namespace clang; 27 28ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) { 29 Diags.setClient(diagClient ? diagClient : new TextDiagnosticBuffer()); 30} 31ASTUnit::~ASTUnit() { 32 if (tempFile) 33 llvm::sys::Path(getPCHFileName()).eraseFromDisk(); 34 35 // The ASTUnit object owns the DiagnosticClient. 36 delete Diags.getClient(); 37} 38 39namespace { 40 41/// \brief Gathers information from PCHReader that will be used to initialize 42/// a Preprocessor. 43class VISIBILITY_HIDDEN PCHInfoCollector : public PCHReaderListener { 44 LangOptions &LangOpt; 45 HeaderSearch &HSI; 46 std::string &TargetTriple; 47 std::string &Predefines; 48 unsigned &Counter; 49 50 unsigned NumHeaderInfos; 51 52public: 53 PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, 54 std::string &TargetTriple, std::string &Predefines, 55 unsigned &Counter) 56 : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), 57 Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} 58 59 virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 60 LangOpt = LangOpts; 61 return false; 62 } 63 64 virtual bool ReadTargetTriple(const std::string &Triple) { 65 TargetTriple = Triple; 66 return false; 67 } 68 69 virtual bool ReadPredefinesBuffer(const char *PCHPredef, 70 unsigned PCHPredefLen, 71 FileID PCHBufferID, 72 std::string &SuggestedPredefines) { 73 Predefines = PCHPredef; 74 return false; 75 } 76 77 virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) { 78 HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 79 } 80 81 virtual void ReadCounter(unsigned Value) { 82 Counter = Value; 83 } 84}; 85 86} // anonymous namespace 87 88const std::string &ASTUnit::getOriginalSourceFileName() { 89 return dyn_cast<PCHReader>(Ctx->getExternalSource())->getOriginalSourceFile(); 90} 91 92const std::string &ASTUnit::getPCHFileName() { 93 return dyn_cast<PCHReader>(Ctx->getExternalSource())->getFileName(); 94} 95 96ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, 97 std::string *ErrMsg, 98 DiagnosticClient *diagClient, 99 bool OnlyLocalDecls, 100 bool UseBumpAllocator) { 101 llvm::OwningPtr<ASTUnit> AST(new ASTUnit(diagClient)); 102 AST->OnlyLocalDecls = OnlyLocalDecls; 103 AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager())); 104 105 // Gather Info for preprocessor construction later on. 106 107 LangOptions LangInfo; 108 HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 109 std::string TargetTriple; 110 std::string Predefines; 111 unsigned Counter; 112 113 llvm::OwningPtr<PCHReader> Reader; 114 llvm::OwningPtr<ExternalASTSource> Source; 115 116 Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), 117 AST->Diags)); 118 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, 119 Predefines, Counter)); 120 121 switch (Reader->ReadPCH(Filename)) { 122 case PCHReader::Success: 123 break; 124 125 case PCHReader::Failure: 126 case PCHReader::IgnorePCH: 127 if (ErrMsg) 128 *ErrMsg = "Could not load PCH file"; 129 return NULL; 130 } 131 132 // PCH loaded successfully. Now create the preprocessor. 133 134 // Get information about the target being compiled for. 135 AST->Target.reset(TargetInfo::CreateTargetInfo(TargetTriple)); 136 AST->PP.reset(new Preprocessor(AST->Diags, LangInfo, *AST->Target.get(), 137 AST->getSourceManager(), HeaderInfo)); 138 Preprocessor &PP = *AST->PP.get(); 139 140 PP.setPredefines(Reader->getSuggestedPredefines()); 141 PP.setCounterValue(Counter); 142 Reader->setPreprocessor(PP); 143 144 // Create and initialize the ASTContext. 145 146 AST->Ctx.reset(new ASTContext(LangInfo, 147 AST->getSourceManager(), 148 *AST->Target.get(), 149 PP.getIdentifierTable(), 150 PP.getSelectorTable(), 151 PP.getBuiltinInfo(), 152 /* FreeMemory = */ !UseBumpAllocator, 153 /* size_reserve = */0)); 154 ASTContext &Context = *AST->Ctx.get(); 155 156 Reader->InitializeContext(Context); 157 158 // Attach the PCH reader to the AST context as an external AST 159 // source, so that declarations will be deserialized from the 160 // PCH file as needed. 161 Source.reset(Reader.take()); 162 Context.setExternalSource(Source); 163 164 return AST.take(); 165} 166