Add CodeCompletion consumer to CompilerInvocation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87100 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2009-11-13 09:36:05 +00:00
Родитель 3a2838d142
Коммит c2f484f1f0
3 изменённых файлов: 90 добавлений и 28 удалений

Просмотреть файл

@ -17,10 +17,12 @@
namespace llvm {
class LLVMContext;
class raw_ostream;
}
namespace clang {
class ASTContext;
class CodeCompleteConsumer;
class Diagnostic;
class DiagnosticClient;
class ExternalASTSource;
@ -77,6 +79,9 @@ class CompilerInstance {
/// The AST context.
llvm::OwningPtr<ASTContext> Context;
/// The code completion consumer.
llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
public:
/// Create a new compiler instance with the given LLVM context, optionally
/// taking ownership of it.
@ -302,6 +307,30 @@ public:
/// takes ownership of \arg Value.
void setASTContext(ASTContext *Value) { Context.reset(Value); }
/// }
/// @name Code Completion
/// {
bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
CodeCompleteConsumer &getCodeCompletionConsumer() const {
assert(CompletionConsumer &&
"Compiler instance has no code completion consumer!");
return *CompletionConsumer;
}
/// takeCodeCompletionConsumer - Remove the current code completion consumer
/// and give ownership to the caller.
CodeCompleteConsumer *takeCodeCompletionConsumer() {
return CompletionConsumer.take();
}
/// setCodeCompletionConsumer - Replace the current code completion consumer;
/// the compiler instance takes ownership of \arg Value.
void setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
CompletionConsumer.reset(Value);
}
/// }
/// @name Construction Utility Methods
/// {
@ -363,6 +392,20 @@ public:
createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
Preprocessor &PP, ASTContext &Context);
/// Create a code completion consumer using the invocation; note that this
/// will cause the source manager to truncate the input source file at the
/// completion point.
void createCodeCompletionConsumer();
/// Create a code completion consumer to print code completion results, at
/// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
/// OS.
static CodeCompleteConsumer *
createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
unsigned Line, unsigned Column,
bool UseDebugPrinter, bool ShowMacros,
llvm::raw_ostream &OS);
/// }
};

Просмотреть файл

@ -18,9 +18,11 @@
#include "clang/Lex/PTHManager.h"
#include "clang/Frontend/ChainedDiagnosticClient.h"
#include "clang/Frontend/PCHReader.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "llvm/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@ -29,7 +31,7 @@ CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext,
bool _OwnsLLVMContext)
: LLVMContext(_LLVMContext),
OwnsLLVMContext(_OwnsLLVMContext) {
}
}
CompilerInstance::~CompilerInstance() {
if (OwnsLLVMContext)
@ -202,3 +204,42 @@ CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
return 0;
}
// Code Completion
void CompilerInstance::createCodeCompletionConsumer() {
const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;
CompletionConsumer.reset(
createCodeCompletionConsumer(getPreprocessor(),
Loc.FileName, Loc.Line, Loc.Column,
getFrontendOpts().DebugCodeCompletionPrinter,
getFrontendOpts().ShowMacrosInCodeCompletion,
llvm::outs()));
}
CodeCompleteConsumer *
CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
const std::string &Filename,
unsigned Line,
unsigned Column,
bool UseDebugPrinter,
bool ShowMacros,
llvm::raw_ostream &OS) {
// Tell the source manager to chop off the given file at a specific
// line and column.
const FileEntry *Entry = PP.getFileManager().getFile(Filename);
if (!Entry) {
PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
<< Filename;
return 0;
}
// Truncate the named file at the given line/column.
PP.getSourceManager().truncateFileAt(Entry, Line, Column);
// Set up the creation routine for code-completion.
if (UseDebugPrinter)
return new PrintingCodeCompleteConsumer(ShowMacros, OS);
else
return new CIndexCodeCompleteConsumer(ShowMacros, OS);
}

Просмотреть файл

@ -481,36 +481,14 @@ static void ProcessInputFile(CompilerInstance &CI, const std::string &InFile,
if (InitializeSourceManager(PP, CI.getFrontendOpts(), InFile))
return;
llvm::OwningPtr<CodeCompleteConsumer> CCConsumer;
if (!FEOpts.CodeCompletionAt.FileName.empty()) {
// Tell the source manager to chop off the given file at a specific
// line and column.
if (const FileEntry *Entry
= PP.getFileManager().getFile(FEOpts.CodeCompletionAt.FileName)) {
// Truncate the named file at the given line/column.
PP.getSourceManager().truncateFileAt(Entry,
FEOpts.CodeCompletionAt.Line,
FEOpts.CodeCompletionAt.Column);
// Set up the creation routine for code-completion.
if (FEOpts.DebugCodeCompletionPrinter)
CCConsumer.reset(
new PrintingCodeCompleteConsumer(FEOpts.ShowMacrosInCodeCompletion,
llvm::outs()));
else
CCConsumer.reset(
new CIndexCodeCompleteConsumer(FEOpts.ShowMacrosInCodeCompletion,
llvm::outs()));
} else {
PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
<< FEOpts.CodeCompletionAt.FileName;
}
}
if (!FEOpts.CodeCompletionAt.FileName.empty())
CI.createCodeCompletionConsumer();
// Run the AST consumer action.
CodeCompleteConsumer *CompletionConsumer =
CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer() : 0;
ParseAST(PP, Consumer.get(), CI.getASTContext(), FEOpts.ShowStats,
CompleteTranslationUnit,
CCConsumer.get());
CompleteTranslationUnit, CompletionConsumer);
} else {
// Initialize builtin info.
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),