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