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