forked from OSchip/llvm-project
Add CodeCompletion consumer to CompilerInvocation.
llvm-svn: 87100
This commit is contained in:
parent
242ea9a05a
commit
f7093b5ae8
|
@ -17,10 +17,12 @@
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class LLVMContext;
|
class LLVMContext;
|
||||||
|
class raw_ostream;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
|
class CodeCompleteConsumer;
|
||||||
class Diagnostic;
|
class Diagnostic;
|
||||||
class DiagnosticClient;
|
class DiagnosticClient;
|
||||||
class ExternalASTSource;
|
class ExternalASTSource;
|
||||||
|
@ -77,6 +79,9 @@ class CompilerInstance {
|
||||||
/// The AST context.
|
/// The AST context.
|
||||||
llvm::OwningPtr<ASTContext> Context;
|
llvm::OwningPtr<ASTContext> Context;
|
||||||
|
|
||||||
|
/// The code completion consumer.
|
||||||
|
llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Create a new compiler instance with the given LLVM context, optionally
|
/// Create a new compiler instance with the given LLVM context, optionally
|
||||||
/// taking ownership of it.
|
/// taking ownership of it.
|
||||||
|
@ -302,6 +307,30 @@ public:
|
||||||
/// takes ownership of \arg Value.
|
/// takes ownership of \arg Value.
|
||||||
void setASTContext(ASTContext *Value) { Context.reset(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
|
/// @name Construction Utility Methods
|
||||||
/// {
|
/// {
|
||||||
|
@ -363,6 +392,20 @@ public:
|
||||||
createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
|
createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
|
||||||
Preprocessor &PP, ASTContext &Context);
|
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/Lex/PTHManager.h"
|
||||||
#include "clang/Frontend/ChainedDiagnosticClient.h"
|
#include "clang/Frontend/ChainedDiagnosticClient.h"
|
||||||
#include "clang/Frontend/PCHReader.h"
|
#include "clang/Frontend/PCHReader.h"
|
||||||
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||||
#include "clang/Frontend/TextDiagnosticBuffer.h"
|
#include "clang/Frontend/TextDiagnosticBuffer.h"
|
||||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||||
#include "clang/Frontend/Utils.h"
|
#include "clang/Frontend/Utils.h"
|
||||||
|
#include "clang/Sema/CodeCompleteConsumer.h"
|
||||||
#include "llvm/LLVMContext.h"
|
#include "llvm/LLVMContext.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
@ -29,7 +31,7 @@ CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext,
|
||||||
bool _OwnsLLVMContext)
|
bool _OwnsLLVMContext)
|
||||||
: LLVMContext(_LLVMContext),
|
: LLVMContext(_LLVMContext),
|
||||||
OwnsLLVMContext(_OwnsLLVMContext) {
|
OwnsLLVMContext(_OwnsLLVMContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerInstance::~CompilerInstance() {
|
CompilerInstance::~CompilerInstance() {
|
||||||
if (OwnsLLVMContext)
|
if (OwnsLLVMContext)
|
||||||
|
@ -202,3 +204,42 @@ CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path,
|
||||||
|
|
||||||
return 0;
|
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))
|
if (InitializeSourceManager(PP, CI.getFrontendOpts(), InFile))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::OwningPtr<CodeCompleteConsumer> CCConsumer;
|
if (!FEOpts.CodeCompletionAt.FileName.empty())
|
||||||
if (!FEOpts.CodeCompletionAt.FileName.empty()) {
|
CI.createCodeCompletionConsumer();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the AST consumer action.
|
// Run the AST consumer action.
|
||||||
|
CodeCompleteConsumer *CompletionConsumer =
|
||||||
|
CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer() : 0;
|
||||||
ParseAST(PP, Consumer.get(), CI.getASTContext(), FEOpts.ShowStats,
|
ParseAST(PP, Consumer.get(), CI.getASTContext(), FEOpts.ShowStats,
|
||||||
CompleteTranslationUnit,
|
CompleteTranslationUnit, CompletionConsumer);
|
||||||
CCConsumer.get());
|
|
||||||
} else {
|
} else {
|
||||||
// Initialize builtin info.
|
// Initialize builtin info.
|
||||||
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
|
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
|
||||||
|
|
Loading…
Reference in New Issue