Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/release/10.x' into rustc/10.0-…
Browse files Browse the repository at this point in the history
…2020-02-05
  • Loading branch information
nikic committed Mar 2, 2020
2 parents 45e825c + 001c8aa commit 3b0e8db
Show file tree
Hide file tree
Showing 235 changed files with 5,232 additions and 1,681 deletions.
12 changes: 12 additions & 0 deletions clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ static std::string getCondVarNames(const Stmt *Cond) {
return Result;
}

static bool isKnownFalse(const Expr &Cond, const ASTContext &Ctx) {
if (Cond.isValueDependent())
return false;
bool Result = false;
if (Cond.EvaluateAsBooleanCondition(Result, Ctx))
return !Result;
return false;
}

void InfiniteLoopCheck::registerMatchers(MatchFinder *Finder) {
const auto LoopCondition = allOf(
hasCondition(
Expand All @@ -170,6 +179,9 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
const auto *LoopStmt = Result.Nodes.getNodeAs<Stmt>("loop-stmt");
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");

if (isKnownFalse(*Cond, *Result.Context))
return;

bool ShouldHaveConditionVariables = true;
if (const auto *While = dyn_cast<WhileStmt>(LoopStmt)) {
if (const VarDecl *LoopVarDecl = While->getConditionVariable()) {
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clangd/CodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1842,6 +1842,8 @@ CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const {
if (InsertInclude && InsertInclude->Insertion)
LSP.additionalTextEdits.push_back(*InsertInclude->Insertion);

LSP.score = Score.ExcludingName;

return LSP;
}

Expand Down
81 changes: 49 additions & 32 deletions clang-tools-extra/clangd/FindTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>
#include <vector>

namespace clang {
namespace clangd {
Expand Down Expand Up @@ -134,6 +135,35 @@ const Type *getPointeeType(const Type *T) {
return FirstArg.getAsType().getTypePtrOrNull();
}

const NamedDecl *getTemplatePattern(const NamedDecl *D) {
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
return CRD->getTemplateInstantiationPattern();
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
return FD->getTemplateInstantiationPattern();
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
// Hmm: getTIP returns its arg if it's not an instantiation?!
VarDecl *T = VD->getTemplateInstantiationPattern();
return (T == D) ? nullptr : T;
} else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
return ED->getInstantiatedFromMemberEnum();
} else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
if (const auto *Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))
if (const DeclContext *ParentPat =
dyn_cast_or_null<DeclContext>(getTemplatePattern(Parent)))
for (const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))
if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())
return BaseND;
} else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
return BaseECD;
}
}
}
return nullptr;
}

// TargetFinder locates the entities that an AST node refers to.
//
// Typically this is (possibly) one declaration and (possibly) one type, but
Expand Down Expand Up @@ -167,37 +197,12 @@ const Type *getPointeeType(const Type *T) {
struct TargetFinder {
using RelSet = DeclRelationSet;
using Rel = DeclRelation;
llvm::SmallDenseMap<const NamedDecl *, RelSet> Decls;
RelSet Flags;

static const NamedDecl *getTemplatePattern(const NamedDecl *D) {
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
return CRD->getTemplateInstantiationPattern();
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
return FD->getTemplateInstantiationPattern();
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
// Hmm: getTIP returns its arg if it's not an instantiation?!
VarDecl *T = VD->getTemplateInstantiationPattern();
return (T == D) ? nullptr : T;
} else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
return ED->getInstantiatedFromMemberEnum();
} else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
if (const auto *Parent = llvm::dyn_cast<NamedDecl>(D->getDeclContext()))
if (const DeclContext *ParentPat =
dyn_cast_or_null<DeclContext>(getTemplatePattern(Parent)))
for (const NamedDecl *BaseND : ParentPat->lookup(D->getDeclName()))
if (!BaseND->isImplicit() && BaseND->getKind() == D->getKind())
return BaseND;
} else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
return BaseECD;
}
}
}
return nullptr;
}
private:
llvm::SmallDenseMap<const NamedDecl *,
std::pair<RelSet, /*InsertionOrder*/ size_t>>
Decls;
RelSet Flags;

template <typename T> void debug(T &Node, RelSet Flags) {
dlog("visit [{0}] {1}", Flags,
Expand All @@ -207,10 +212,22 @@ struct TargetFinder {
void report(const NamedDecl *D, RelSet Flags) {
dlog("--> [{0}] {1}", Flags,
nodeToString(ast_type_traits::DynTypedNode::create(*D)));
Decls[D] |= Flags;
auto It = Decls.try_emplace(D, std::make_pair(Flags, Decls.size()));
// If already exists, update the flags.
if (!It.second)
It.first->second.first |= Flags;
}

public:
llvm::SmallVector<std::pair<const NamedDecl *, RelSet>, 1> takeDecls() const {
using ValTy = std::pair<const NamedDecl *, RelSet>;
llvm::SmallVector<ValTy, 1> Result;
Result.resize(Decls.size());
for (const auto &Elem : Decls)
Result[Elem.second.second] = {Elem.first, Elem.second.first};
return Result;
}

void add(const Decl *Dcl, RelSet Flags) {
const NamedDecl *D = llvm::dyn_cast<NamedDecl>(Dcl);
if (!D)
Expand Down Expand Up @@ -485,7 +502,7 @@ allTargetDecls(const ast_type_traits::DynTypedNode &N) {
else if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>())
Finder.add(CCI, Flags);

return {Finder.Decls.begin(), Finder.Decls.end()};
return Finder.takeDecls();
}

llvm::SmallVector<const NamedDecl *, 1>
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@ llvm::json::Value toJSON(const CompletionItem &CI) {
Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits);
if (CI.deprecated)
Result["deprecated"] = CI.deprecated;
Result["score"] = CI.score;
return std::move(Result);
}

Expand Down
7 changes: 7 additions & 0 deletions clang-tools-extra/clangd/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,13 @@ struct CompletionItem {
/// Indicates if this item is deprecated.
bool deprecated = false;

/// This is Clangd extension.
/// The score that Clangd calculates to rank completion items. This score can
/// be used to adjust the ranking on the client side.
/// NOTE: This excludes fuzzy matching score which is typically calculated on
/// the client side.
float score = 0.f;

// TODO(krasimir): The following optional fields defined by the language
// server protocol are unsupported:
//
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/test/completion-auto-trigger.test
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " size",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}size",
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "size",
Expand All @@ -46,6 +47,7 @@
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 10,
# CHECK-NEXT: "label": " default_capacity",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}default_capacity",
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "default_capacity",
Expand Down Expand Up @@ -86,6 +88,7 @@
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 6,
# CHECK-NEXT: "label": " ns_member",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}ns_member",
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "ns_member",
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/test/completion-snippets.test
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
# CHECK-NEXT: "insertTextFormat": 2,
# CHECK-NEXT: "kind": 3,
# CHECK-NEXT: "label": " func_with_args(int a, int b)",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}func_with_args"
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "func_with_args(${1:int a}, ${2:int b})",
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clangd/test/completion.test
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " a",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}a"
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "a",
Expand Down Expand Up @@ -50,6 +51,7 @@
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " b",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}b"
# CHECK-NEXT: "textEdit": {
# CHECK-NEXT: "newText": "b",
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/test/protocol.test
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Content-Length: 146
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " a",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}"
# CHECK: ]
# CHECK-NEXT: }
Expand Down Expand Up @@ -68,6 +69,7 @@ Content-Length: 146
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " a",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}"
# CHECK: ]
# CHECK-NEXT: }
Expand Down Expand Up @@ -97,6 +99,7 @@ Content-Length: 146
# CHECK-NEXT: "insertTextFormat": 1,
# CHECK-NEXT: "kind": 5,
# CHECK-NEXT: "label": " a",
# CHECK-NEXT: "score": {{[0-9]+.[0-9]+}},
# CHECK-NEXT: "sortText": "{{.*}}"
# CHECK: ]
# CHECK-NEXT: }
Expand Down
2 changes: 2 additions & 0 deletions clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,7 @@ TEST(CompletionTest, Render) {
Include.Header = "\"foo.h\"";
C.Kind = CompletionItemKind::Method;
C.Score.Total = 1.0;
C.Score.ExcludingName = .5;
C.Origin = SymbolOrigin::AST | SymbolOrigin::Static;

CodeCompleteOptions Opts;
Expand All @@ -1660,6 +1661,7 @@ TEST(CompletionTest, Render) {
EXPECT_THAT(R.additionalTextEdits, IsEmpty());
EXPECT_EQ(R.sortText, sortText(1.0, "x"));
EXPECT_FALSE(R.deprecated);
EXPECT_EQ(R.score, .5f);

Opts.EnableSnippets = true;
R = C.render(Opts);
Expand Down
Loading

0 comments on commit 3b0e8db

Please sign in to comment.