diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:35 +0000 | 
|---|---|---|
| committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:35 +0000 | 
| commit | b897c8660c4ff7037dde81b9645737bc1c992abe (patch) | |
| tree | b6403365e77095a79062d3379c9e6aea0df5f088 /lib/Frontend/ASTUnit.cpp | |
| parent | 7ef7bab7e3d06f660b059b903c231f100bb13cc5 (diff) | |
Notes
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
| -rw-r--r-- | lib/Frontend/ASTUnit.cpp | 159 | 
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp new file mode 100644 index 000000000000..a7fbcda8fc2b --- /dev/null +++ b/lib/Frontend/ASTUnit.cpp @@ -0,0 +1,159 @@ +//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// ASTUnit Implementation. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/PCHReader.h" +#include "clang/Frontend/TextDiagnosticBuffer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclVisitor.h" +#include "clang/AST/StmtVisitor.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Diagnostic.h" +#include "llvm/Support/Compiler.h" + +using namespace clang; + +ASTUnit::ASTUnit() { } +ASTUnit::~ASTUnit() { } + +namespace { + +/// \brief Gathers information from PCHReader that will be used to initialize +/// a Preprocessor. +class VISIBILITY_HIDDEN PCHInfoCollector : public PCHReaderListener { +  LangOptions &LangOpt; +  HeaderSearch &HSI; +  std::string &TargetTriple; +  std::string &Predefines; +  unsigned &Counter; +   +  unsigned NumHeaderInfos; +   +public: +  PCHInfoCollector(LangOptions &LangOpt, HeaderSearch &HSI, +                   std::string &TargetTriple, std::string &Predefines, +                   unsigned &Counter) +    : LangOpt(LangOpt), HSI(HSI), TargetTriple(TargetTriple), +      Predefines(Predefines), Counter(Counter), NumHeaderInfos(0) {} +   +  virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { +    LangOpt = LangOpts; +    return false; +  } +   +  virtual bool ReadTargetTriple(const std::string &Triple) { +    TargetTriple = Triple; +    return false; +  } +   +  virtual bool ReadPredefinesBuffer(const char *PCHPredef,  +                                    unsigned PCHPredefLen, +                                    FileID PCHBufferID, +                                    std::string &SuggestedPredefines) { +    Predefines = PCHPredef; +    return false; +  } +   +  virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI) { +    HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); +  } +   +  virtual void ReadCounter(unsigned Value) { +    Counter = Value; +  } +}; + +} // anonymous namespace + + +ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, +                                  FileManager &FileMgr, +                                  std::string *ErrMsg) { +   +  llvm::OwningPtr<ASTUnit> AST(new ASTUnit()); + +  AST->DiagClient.reset(new TextDiagnosticBuffer()); +  AST->Diags.reset(new Diagnostic(AST->DiagClient.get())); + +  AST->HeaderInfo.reset(new HeaderSearch(FileMgr)); +  AST->SourceMgr.reset(new SourceManager()); +   +  Diagnostic &Diags = *AST->Diags.get(); +  SourceManager &SourceMgr = *AST->SourceMgr.get(); + +  // Gather Info for preprocessor construction later on. +   +  LangOptions LangInfo; +  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); +  std::string TargetTriple; +  std::string Predefines; +  unsigned Counter; + +  llvm::OwningPtr<PCHReader> Reader; +  llvm::OwningPtr<ExternalASTSource> Source; + +  Reader.reset(new PCHReader(SourceMgr, FileMgr, Diags)); +  Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, +                                           Predefines, Counter)); + +  switch (Reader->ReadPCH(Filename)) { +  case PCHReader::Success: +    break; +     +  case PCHReader::Failure: +    // Unrecoverable failure: don't even try to process the input +    // file. +    if (ErrMsg) +      *ErrMsg = "Could not load PCH file"; +    return NULL; + +  case PCHReader::IgnorePCH: +    assert(0 && "Is there a validation that should not have happened ?"); +  } +   +  // PCH loaded successfully. Now create the preprocessor. +   +  // Get information about the target being compiled for. +  AST->Target.reset(TargetInfo::CreateTargetInfo(TargetTriple)); +  AST->PP.reset(new Preprocessor(Diags, LangInfo, *AST->Target.get(), +                                 SourceMgr, HeaderInfo)); +  Preprocessor &PP = *AST->PP.get(); + +  PP.setPredefines(Predefines); +  PP.setCounterValue(Counter); +  Reader->setPreprocessor(PP); +   +  // Create and initialize the ASTContext. + +  AST->Ctx.reset(new ASTContext(LangInfo, +                                SourceMgr, +                                *AST->Target.get(), +                                PP.getIdentifierTable(), +                                PP.getSelectorTable(), +                                PP.getBuiltinInfo(), +                                /* FreeMemory = */ true, +                                /* size_reserve = */0)); +  ASTContext &Context = *AST->Ctx.get(); +   +  Reader->InitializeContext(Context); +   +  // Attach the PCH reader to the AST context as an external AST +  // source, so that declarations will be deserialized from the +  // PCH file as needed. +  Source.reset(Reader.take()); +  Context.setExternalSource(Source); + +  return AST.take();  +}  | 
