ASTUnit.cpp revision bce6f62ae7d2c15992617f64e30067803fb5b47f
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 80 81ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, 82 FileManager &FileMgr, 83 std::string *ErrMsg) { 84 85 llvm::OwningPtr<ASTUnit> AST(new ASTUnit()); 86 87 AST->DiagClient.reset(new TextDiagnosticBuffer()); 88 AST->Diags.reset(new Diagnostic(AST->DiagClient.get())); 89 90 AST->HeaderInfo.reset(new HeaderSearch(FileMgr)); 91 AST->SourceMgr.reset(new SourceManager()); 92 93 Diagnostic &Diags = *AST->Diags.get(); 94 SourceManager &SourceMgr = *AST->SourceMgr.get(); 95 96 // Gather Info for preprocessor construction later on. 97 98 LangOptions LangInfo; 99 HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 100 std::string TargetTriple; 101 std::string Predefines; 102 unsigned Counter; 103 104 llvm::OwningPtr<PCHReader> Reader; 105 llvm::OwningPtr<ExternalASTSource> Source; 106 107 Reader.reset(new PCHReader(SourceMgr, FileMgr, Diags)); 108 Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, 109 Predefines, Counter)); 110 111 switch (Reader->ReadPCH(Filename)) { 112 case PCHReader::Success: 113 break; 114 115 case PCHReader::Failure: 116 case PCHReader::IgnorePCH: 117 if (ErrMsg) 118 *ErrMsg = "Could not load PCH file"; 119 return NULL; 120 } 121 122 // PCH loaded successfully. Now create the preprocessor. 123 124 // Get information about the target being compiled for. 125 AST->Target.reset(TargetInfo::CreateTargetInfo(TargetTriple)); 126 AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(), 127 SourceMgr, HeaderInfo)); 128 Preprocessor &PP = *AST->PP.get(); 129 130 PP.setPredefines(Predefines); 131 PP.setCounterValue(Counter); 132 Reader->setPreprocessor(PP); 133 134 // Create and initialize the ASTContext. 135 136 AST->Ctx.reset(new ASTContext(LangInfo, 137 SourceMgr, 138 *AST->Target.get(), 139 PP.getIdentifierTable(), 140 PP.getSelectorTable(), 141 PP.getBuiltinInfo(), 142 /* FreeMemory = */ true, 143 /* size_reserve = */0)); 144 ASTContext &Context = *AST->Ctx.get(); 145 146 Reader->InitializeContext(Context); 147 148 // Attach the PCH reader to the AST context as an external AST 149 // source, so that declarations will be deserialized from the 150 // PCH file as needed. 151 Source.reset(Reader.take()); 152 Context.setExternalSource(Source); 153 154 return AST.take(); 155} 156