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