зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
3a2838d142
Коммит
c2f484f1f0
|
@ -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(),
|
||||
|
|
Загрузка…
Ссылка в новой задаче