forked from OSchip/llvm-project
Introduce the ASTUnit class.
ASTUnit is a helper class to allow easy loading of an ASTContext from a PCH file. No users for now. llvm-svn: 73819
This commit is contained in:
parent
9fc4db5615
commit
ce3797527e
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H
|
||||||
|
#define LLVM_CLANG_FRONTEND_ASTUNIT_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
class FileManager;
|
||||||
|
class FileEntry;
|
||||||
|
class SourceManager;
|
||||||
|
class DiagnosticClient;
|
||||||
|
class Diagnostic;
|
||||||
|
class HeaderSearch;
|
||||||
|
class TargetInfo;
|
||||||
|
class Preprocessor;
|
||||||
|
class ASTContext;
|
||||||
|
class Decl;
|
||||||
|
|
||||||
|
/// \brief Utility class for loading a ASTContext from a PCH file.
|
||||||
|
///
|
||||||
|
class ASTUnit {
|
||||||
|
llvm::OwningPtr<SourceManager> SourceMgr;
|
||||||
|
llvm::OwningPtr<DiagnosticClient> DiagClient;
|
||||||
|
llvm::OwningPtr<Diagnostic> Diags;
|
||||||
|
llvm::OwningPtr<HeaderSearch> HeaderInfo;
|
||||||
|
llvm::OwningPtr<TargetInfo> Target;
|
||||||
|
llvm::OwningPtr<Preprocessor> PP;
|
||||||
|
llvm::OwningPtr<ASTContext> Ctx;
|
||||||
|
|
||||||
|
ASTUnit(const ASTUnit&); // do not implement
|
||||||
|
ASTUnit &operator=(const ASTUnit &); // do not implement
|
||||||
|
ASTUnit();
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ASTUnit();
|
||||||
|
|
||||||
|
const SourceManager &getSourceManager() const { return *SourceMgr.get(); }
|
||||||
|
SourceManager &getSourceManager() { return *SourceMgr.get(); }
|
||||||
|
|
||||||
|
const Preprocessor &getPreprocessor() const { return *PP.get(); }
|
||||||
|
Preprocessor &getPreprocessor() { return *PP.get(); }
|
||||||
|
|
||||||
|
const ASTContext &getASTContext() const { return *Ctx.get(); }
|
||||||
|
ASTContext &getASTContext() { return *Ctx.get(); }
|
||||||
|
|
||||||
|
/// \brief Create a ASTUnit from a PCH file.
|
||||||
|
///
|
||||||
|
/// \param Filename PCH filename
|
||||||
|
///
|
||||||
|
/// \param FileMgr The FileManager to use
|
||||||
|
///
|
||||||
|
/// \param ErrMsg Error message to report if the PCH file could not be loaded
|
||||||
|
///
|
||||||
|
/// \returns the initialized ASTUnit or NULL if the PCH failed to load
|
||||||
|
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
|
||||||
|
FileManager &FileMgr,
|
||||||
|
std::string *ErrMsg = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace clang
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,146 @@
|
||||||
|
#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();
|
||||||
|
}
|
Loading…
Reference in New Issue