diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-12-01 09:51:01 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-12-01 09:51:01 +0000 |
commit | 521bf9c529e653ab28896d027352d3e16e2672d5 (patch) | |
tree | 9e42e1b5d84aef7e15c945b03844a40975637fc8 /lib/Frontend/ASTUnit.cpp | |
parent | d8fdde119630fa717457ab23b077f447bb2e9e3a (diff) |
Add ASTUnit::LoadFromCompilerInvocation, which does what it says.
Also, add an -ast-from-source option to index-test which allows index-test to
run on source files directly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90223 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 99 |
1 files changed, 95 insertions, 4 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 9e9d216ef7..f647c8a237 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -14,24 +14,28 @@ #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/PCHReader.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConsumer.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/FrontendOptions.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/Diagnostic.h" +#include "llvm/LLVMContext.h" #include "llvm/System/Path.h" - using namespace clang; -ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) { +ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) { Diags.setClient(diagClient ? diagClient : new TextDiagnosticBuffer()); } -ASTUnit::~ASTUnit() { +ASTUnit::~ASTUnit() { if (tempFile) llvm::sys::Path(getPCHFileName()).eraseFromDisk(); - + // The ASTUnit object owns the DiagnosticClient. delete Diags.getClient(); } @@ -170,3 +174,90 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, return AST.take(); } + +namespace { + +class NullAction : public ASTFrontendAction { + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + return new ASTConsumer(); + } + +public: + virtual bool hasCodeCompletionSupport() const { return false; } +}; + +} + +ASTUnit *ASTUnit::LoadFromCompilerInvocation(const CompilerInvocation &CI, + Diagnostic &Diags, + bool OnlyLocalDecls, + bool UseBumpAllocator) { + // Create the compiler instance to use for building the AST. + CompilerInstance Clang(&llvm::getGlobalContext(), false); + llvm::OwningPtr<ASTUnit> AST; + NullAction Act; + + Clang.getInvocation() = CI; + + Clang.setDiagnostics(&Diags); + Clang.setDiagnosticClient(Diags.getClient()); + + // Create the target instance. + Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(), + Clang.getTargetOpts())); + if (!Clang.hasTarget()) + goto error; + + // Inform the target of the language options. + // + // FIXME: We shouldn't need to do this, the target should be immutable once + // created. This complexity should be lifted elsewhere. + Clang.getTarget().setForcedLangOptions(Clang.getLangOpts()); + + assert(Clang.getFrontendOpts().Inputs.size() == 1 && + "Invocation must have exactly one source file!"); + assert(Clang.getFrontendOpts().Inputs[0].first != FrontendOptions::IK_AST && + "FIXME: AST inputs not yet supported here!"); + + // Create the AST unit. + // + // FIXME: Use the provided diagnostic client. + AST.reset(new ASTUnit()); + + // Create a file manager object to provide access to and cache the filesystem. + Clang.setFileManager(&AST->getFileManager()); + + // Create the source manager. + Clang.setSourceManager(&AST->getSourceManager()); + + // Create the preprocessor. + Clang.createPreprocessor(); + + if (!Act.BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second, + /*IsAST=*/false)) + goto error; + + Act.Execute(); + + // Steal the created context and preprocessor, and take back the source and + // file managers. + AST->Ctx.reset(Clang.takeASTContext()); + AST->PP.reset(Clang.takePreprocessor()); + Clang.takeSourceManager(); + Clang.takeFileManager(); + + Act.EndSourceFile(); + + Clang.takeDiagnosticClient(); + Clang.takeDiagnostics(); + + return AST.take(); + +error: + Clang.takeSourceManager(); + Clang.takeFileManager(); + Clang.takeDiagnosticClient(); + Clang.takeDiagnostics(); + return 0; +} |