summaryrefslogtreecommitdiff
path: root/lib/Sema/CodeCompleteConsumer.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Sema/CodeCompleteConsumer.cpp
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
Notes
Diffstat (limited to 'lib/Sema/CodeCompleteConsumer.cpp')
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp162
1 files changed, 127 insertions, 35 deletions
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 3431ddcf70a23..9c4d315a692f8 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -1,4 +1,4 @@
-//===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
+//===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,21 +10,30 @@
// This file implements the CodeCompleteConsumer class.
//
//===----------------------------------------------------------------------===//
+
#include "clang/Sema/CodeCompleteConsumer.h"
#include "clang-c/Index.h"
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
-#include "clang/Sema/Scope.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Sema/Sema.h"
#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <cstring>
-#include <functional>
+#include <cassert>
+#include <cstdint>
+#include <string>
using namespace clang;
@@ -33,7 +42,7 @@ using namespace clang;
//===----------------------------------------------------------------------===//
bool CodeCompletionContext::wantConstructorResults() const {
- switch (Kind) {
+ switch (CCKind) {
case CCC_Recovery:
case CCC_Statement:
case CCC_Expression:
@@ -76,12 +85,87 @@ bool CodeCompletionContext::wantConstructorResults() const {
llvm_unreachable("Invalid CodeCompletionContext::Kind!");
}
+StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
+ using CCKind = CodeCompletionContext::Kind;
+ switch (Kind) {
+ case CCKind::CCC_Other:
+ return "Other";
+ case CCKind::CCC_OtherWithMacros:
+ return "OtherWithMacros";
+ case CCKind::CCC_TopLevel:
+ return "TopLevel";
+ case CCKind::CCC_ObjCInterface:
+ return "ObjCInterface";
+ case CCKind::CCC_ObjCImplementation:
+ return "ObjCImplementation";
+ case CCKind::CCC_ObjCIvarList:
+ return "ObjCIvarList";
+ case CCKind::CCC_ClassStructUnion:
+ return "ClassStructUnion";
+ case CCKind::CCC_Statement:
+ return "Statement";
+ case CCKind::CCC_Expression:
+ return "Expression";
+ case CCKind::CCC_ObjCMessageReceiver:
+ return "ObjCMessageReceiver";
+ case CCKind::CCC_DotMemberAccess:
+ return "DotMemberAccess";
+ case CCKind::CCC_ArrowMemberAccess:
+ return "ArrowMemberAccess";
+ case CCKind::CCC_ObjCPropertyAccess:
+ return "ObjCPropertyAccess";
+ case CCKind::CCC_EnumTag:
+ return "EnumTag";
+ case CCKind::CCC_UnionTag:
+ return "UnionTag";
+ case CCKind::CCC_ClassOrStructTag:
+ return "ClassOrStructTag";
+ case CCKind::CCC_ObjCProtocolName:
+ return "ObjCProtocolName";
+ case CCKind::CCC_Namespace:
+ return "Namespace";
+ case CCKind::CCC_Type:
+ return "Type";
+ case CCKind::CCC_Name:
+ return "Name";
+ case CCKind::CCC_PotentiallyQualifiedName:
+ return "PotentiallyQualifiedName";
+ case CCKind::CCC_MacroName:
+ return "MacroName";
+ case CCKind::CCC_MacroNameUse:
+ return "MacroNameUse";
+ case CCKind::CCC_PreprocessorExpression:
+ return "PreprocessorExpression";
+ case CCKind::CCC_PreprocessorDirective:
+ return "PreprocessorDirective";
+ case CCKind::CCC_NaturalLanguage:
+ return "NaturalLanguage";
+ case CCKind::CCC_SelectorName:
+ return "SelectorName";
+ case CCKind::CCC_TypeQualifiers:
+ return "TypeQualifiers";
+ case CCKind::CCC_ParenthesizedExpression:
+ return "ParenthesizedExpression";
+ case CCKind::CCC_ObjCInstanceMessage:
+ return "ObjCInstanceMessage";
+ case CCKind::CCC_ObjCClassMessage:
+ return "ObjCClassMessage";
+ case CCKind::CCC_ObjCInterfaceName:
+ return "ObjCInterfaceName";
+ case CCKind::CCC_ObjCCategoryName:
+ return "ObjCCategoryName";
+ case CCKind::CCC_Recovery:
+ return "Recovery";
+ }
+ llvm_unreachable("Invalid CodeCompletionContext::Kind!");
+}
+
//===----------------------------------------------------------------------===//
// Code completion string implementation
//===----------------------------------------------------------------------===//
+
CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
- : Kind(Kind), Text("")
-{
+ : Kind(Kind), Text("") {
switch (Kind) {
case CK_TypedText:
case CK_Text:
@@ -195,10 +279,9 @@ CodeCompletionString::CodeCompletionString(const Chunk *Chunks,
unsigned NumAnnotations,
StringRef ParentName,
const char *BriefComment)
- : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
- Priority(Priority), Availability(Availability),
- ParentName(ParentName), BriefComment(BriefComment)
-{
+ : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
+ Priority(Priority), Availability(Availability),
+ ParentName(ParentName), BriefComment(BriefComment) {
assert(NumChunks <= 0xffff);
assert(NumAnnotations <= 0xffff);
@@ -222,7 +305,6 @@ const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
return nullptr;
}
-
std::string CodeCompletionString::getAsString() const {
std::string Result;
llvm::raw_string_ostream OS(Result);
@@ -267,7 +349,7 @@ const char *CodeCompletionAllocator::CopyString(const Twine &String) {
StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
if (!ND)
- return StringRef();
+ return {};
// Check whether we've already cached the parent name.
StringRef &CachedParentName = ParentNames[DC];
@@ -277,7 +359,7 @@ StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
// If we already processed this DeclContext and assigned empty to it, the
// data pointer will be non-null.
if (CachedParentName.data() != nullptr)
- return StringRef();
+ return {};
// Find the interesting names.
SmallVector<const DeclContext *, 2> Contexts;
@@ -311,7 +393,7 @@ StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
// Assign an empty StringRef but with non-null data to distinguish
// between empty because we didn't process the DeclContext yet.
CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
- return StringRef();
+ return {};
}
OS << Interface->getName() << '(' << Cat->getName() << ')';
@@ -375,9 +457,8 @@ void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
}
void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
- if (DC->isTranslationUnit()) {
+ if (DC->isTranslationUnit())
return;
- }
if (DC->isFunctionOrMethod())
return;
@@ -427,25 +508,21 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
// Code completion consumer implementation
//===----------------------------------------------------------------------===//
-CodeCompleteConsumer::~CodeCompleteConsumer() { }
+CodeCompleteConsumer::~CodeCompleteConsumer() = default;
bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter,
CodeCompletionResult Result) {
switch (Result.Kind) {
- case CodeCompletionResult::RK_Declaration: {
+ case CodeCompletionResult::RK_Declaration:
return !(Result.Declaration->getIdentifier() &&
Result.Declaration->getIdentifier()->getName().startswith(Filter));
- }
- case CodeCompletionResult::RK_Keyword: {
+ case CodeCompletionResult::RK_Keyword:
return !StringRef(Result.Keyword).startswith(Filter);
- }
- case CodeCompletionResult::RK_Macro: {
+ case CodeCompletionResult::RK_Macro:
return !Result.Macro->getName().startswith(Filter);
- }
- case CodeCompletionResult::RK_Pattern: {
+ case CodeCompletionResult::RK_Pattern:
return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
}
- }
llvm_unreachable("Unknown code completion result Kind.");
}
@@ -477,7 +554,24 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
if (const char *BriefComment = CCS->getBriefComment())
OS << " : " << BriefComment;
}
-
+ for (const FixItHint &FixIt : Results[I].FixIts) {
+ const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
+ const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
+
+ SourceManager &SM = SemaRef.SourceMgr;
+ std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
+ std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
+ // Adjust for token ranges.
+ if (FixIt.RemoveRange.isTokenRange())
+ EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
+
+ OS << " (requires fix-it:"
+ << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
+ << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
+ << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
+ << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
+ << " to \"" << FixIt.CodeToInsert << "\")";
+ }
OS << '\n';
break;
@@ -485,7 +579,7 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << Results[I].Keyword << '\n';
break;
- case CodeCompletionResult::RK_Macro: {
+ case CodeCompletionResult::RK_Macro:
OS << Results[I].Macro->getName();
if (CodeCompletionString *CCS
= Results[I].CreateCodeCompletionString(SemaRef, Context,
@@ -496,14 +590,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
}
OS << '\n';
break;
- }
- case CodeCompletionResult::RK_Pattern: {
+ case CodeCompletionResult::RK_Pattern:
OS << "Pattern : "
<< Results[I].Pattern->getAsString() << '\n';
break;
}
- }
}
}
@@ -547,7 +639,7 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
}
}
-/// \brief Retrieve the effective availability of the given declaration.
+/// Retrieve the effective availability of the given declaration.
static AvailabilityResult getDeclAvailability(const Decl *D) {
AvailabilityResult AR = D->getAvailability();
if (isa<EnumConstantDecl>(D))
@@ -609,7 +701,7 @@ void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
Availability = CXAvailability_NotAccessible;
}
-/// \brief Retrieve the name that should be used to order a result.
+/// Retrieve the name that should be used to order a result.
///
/// If the name needs to be constructed as a string, that string will be
/// saved into Saved and the returned StringRef will refer to it.