Skip to content

Commit c6f5e7e

Browse files
committed
Merge from 'master' to 'sycl-web' (#1)
2 parents 6ab90eb + accc6b5 commit c6f5e7e

File tree

1,698 files changed

+40864
-18007
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,698 files changed

+40864
-18007
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,7 @@ SignatureHelp signatureHelp(PathRef FileName,
17771777
const SymbolIndex *Index) {
17781778
auto Offset = positionToOffset(Contents, Pos);
17791779
if (!Offset) {
1780-
elog("Code completion position was invalid {0}", Offset.takeError());
1780+
elog("Signature help position was invalid {0}", Offset.takeError());
17811781
return SignatureHelp();
17821782
}
17831783
SignatureHelp Result;

clang-tools-extra/clangd/Compiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
8282
CI->getPreprocessorOpts().PCHThroughHeader.clear();
8383
CI->getPreprocessorOpts().PCHWithHdrStop = false;
8484
CI->getPreprocessorOpts().PCHWithHdrStopCreate = false;
85+
86+
// Recovery expression currently only works for C++.
87+
if (CI->getLangOpts()->CPlusPlus)
88+
CI->getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST;
8589
return CI;
8690
}
8791

clang-tools-extra/clangd/Diagnostics.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ Range diagnosticRange(const clang::Diagnostic &D, const LangOptions &L) {
124124
bool adjustDiagFromHeader(Diag &D, const clang::Diagnostic &Info,
125125
const LangOptions &LangOpts) {
126126
// We only report diagnostics with at least error severity from headers.
127-
if (D.Severity < DiagnosticsEngine::Level::Error)
127+
// Use default severity to avoid noise with -Werror.
128+
if (!Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError(
129+
Info.getID()))
128130
return false;
129131

130132
const SourceManager &SM = Info.getSourceManager();
@@ -514,7 +516,8 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
514516
if (Info.getLocation().isInvalid()) {
515517
// Handle diagnostics coming from command-line arguments. The source manager
516518
// is *not* available at this point, so we cannot use it.
517-
if (DiagLevel < DiagnosticsEngine::Level::Error) {
519+
if (!Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError(
520+
Info.getID())) {
518521
IgnoreDiagnostics::log(DiagLevel, Info);
519522
return; // non-errors add too much noise, do not show them.
520523
}

clang-tools-extra/clangd/ParsedAST.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,6 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
262262
const PrecompiledPreamble *PreamblePCH =
263263
Preamble ? &Preamble->Preamble : nullptr;
264264

265-
// Recovery expression currently only works for C++.
266-
if (CI->getLangOpts()->CPlusPlus)
267-
CI->getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST;
268265
// This is on-by-default in windows to allow parsing SDK headers, but it
269266
// breaks many features. Disable it for the main-file (not preamble).
270267
CI->getLangOpts()->DelayedTemplateParsing = false;
@@ -314,18 +311,12 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
314311
std::string CheckName = CTContext->getCheckName(Info.getID());
315312
bool IsClangTidyDiag = !CheckName.empty();
316313
if (IsClangTidyDiag) {
317-
// Check for warning-as-error.
318-
// We deliberately let this take precedence over suppression comments
319-
// to match clang-tidy's behaviour.
320-
if (DiagLevel == DiagnosticsEngine::Warning &&
321-
CTContext->treatAsError(CheckName)) {
322-
return DiagnosticsEngine::Error;
323-
}
324-
325314
// Check for suppression comment. Skip the check for diagnostics not
326315
// in the main file, because we don't want that function to query the
327316
// source buffer for preamble files. For the same reason, we ask
328317
// shouldSuppressDiagnostic to avoid I/O.
318+
// We let suppression comments take precedence over warning-as-error
319+
// to match clang-tidy's behaviour.
329320
bool IsInsideMainFile =
330321
Info.hasSourceManager() &&
331322
isInsideMainFile(Info.getLocation(), Info.getSourceManager());
@@ -334,6 +325,12 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
334325
/*AllowIO=*/false)) {
335326
return DiagnosticsEngine::Ignored;
336327
}
328+
329+
// Check for warning-as-error.
330+
if (DiagLevel == DiagnosticsEngine::Warning &&
331+
CTContext->treatAsError(CheckName)) {
332+
return DiagnosticsEngine::Error;
333+
}
337334
}
338335
}
339336
return DiagLevel;

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,6 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
219219
// to read back. We rely on dynamic index for the comments instead.
220220
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
221221

222-
// Recovery expression currently only works for C++.
223-
if (CI.getLangOpts()->CPlusPlus)
224-
CI.getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST;
225-
226222
CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
227223
if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
228224
log("Couldn't set working directory when building the preamble.");

clang-tools-extra/clangd/Selection.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Selection.h"
1010
#include "SourceCode.h"
1111
#include "support/Logger.h"
12+
#include "support/Trace.h"
1213
#include "clang/AST/ASTTypeTraits.h"
1314
#include "clang/AST/Decl.h"
1415
#include "clang/AST/DeclCXX.h"
@@ -35,6 +36,21 @@ namespace {
3536
using Node = SelectionTree::Node;
3637
using ast_type_traits::DynTypedNode;
3738

39+
// Measure the fraction of selections that were enabled by recovery AST.
40+
void recordMetrics(const SelectionTree &S) {
41+
static constexpr trace::Metric SelectionUsedRecovery(
42+
"selection_recovery", trace::Metric::Distribution);
43+
const auto *Common = S.commonAncestor();
44+
for (const auto *N = Common; N; N = N->Parent) {
45+
if (N->ASTNode.get<RecoveryExpr>()) {
46+
SelectionUsedRecovery.record(1); // used recovery ast.
47+
return;
48+
}
49+
}
50+
if (Common)
51+
SelectionUsedRecovery.record(0); // unused.
52+
}
53+
3854
// An IntervalSet maintains a set of disjoint subranges of an array.
3955
//
4056
// Initially, it contains the entire array.
@@ -774,6 +790,7 @@ SelectionTree::SelectionTree(ASTContext &AST, const syntax::TokenBuffer &Tokens,
774790
.printToString(SM));
775791
Nodes = SelectionVisitor::collect(AST, Tokens, PrintPolicy, Begin, End, FID);
776792
Root = Nodes.empty() ? nullptr : &Nodes.front();
793+
recordMetrics(*this);
777794
dlog("Built selection tree\n{0}", *this);
778795
}
779796

clang-tools-extra/clangd/benchmarks/IndexBenchmark.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ static void DexQueries(benchmark::State &State) {
8383
}
8484
BENCHMARK(DexQueries);
8585

86+
static void DexBuild(benchmark::State &State) {
87+
for (auto _ : State)
88+
buildDex();
89+
}
90+
BENCHMARK(DexBuild);
91+
8692
} // namespace
8793
} // namespace clangd
8894
} // namespace clang

clang-tools-extra/clangd/index/dex/Dex.cpp

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,60 @@ namespace {
3939
const Token RestrictedForCodeCompletion =
4040
Token(Token::Kind::Sentinel, "Restricted For Code Completion");
4141

42-
// Returns the tokens which are given symbol's characteristics. Currently, the
43-
// generated tokens only contain fuzzy matching trigrams and symbol's scope,
44-
// but in the future this will also return path proximity tokens and other
45-
// types of tokens such as symbol type (if applicable).
46-
// Returns the tokens which are given symbols's characteristics. For example,
47-
// trigrams and scopes.
48-
// FIXME(kbobyrev): Support more token types:
49-
// * Namespace proximity
50-
std::vector<Token> generateSearchTokens(const Symbol &Sym) {
51-
std::vector<Token> Result = generateIdentifierTrigrams(Sym.Name);
52-
Result.emplace_back(Token::Kind::Scope, Sym.Scope);
53-
// Skip token generation for symbols with unknown declaration location.
54-
if (!llvm::StringRef(Sym.CanonicalDeclaration.FileURI).empty())
55-
for (const auto &ProximityURI :
56-
generateProximityURIs(Sym.CanonicalDeclaration.FileURI))
57-
Result.emplace_back(Token::Kind::ProximityURI, ProximityURI);
58-
if (Sym.Flags & Symbol::IndexedForCodeCompletion)
59-
Result.emplace_back(RestrictedForCodeCompletion);
60-
if (!Sym.Type.empty())
61-
Result.emplace_back(Token::Kind::Type, Sym.Type);
62-
return Result;
63-
}
42+
// Helper to efficiently assemble the inverse index (token -> matching docs).
43+
// The output is a nice uniform structure keyed on Token, but constructing
44+
// the Token object every time we want to insert into the map is wasteful.
45+
// Instead we have various maps keyed on things that are cheap to compute,
46+
// and produce the Token keys once at the end.
47+
class IndexBuilder {
48+
llvm::DenseMap<Trigram, std::vector<DocID>> TrigramDocs;
49+
std::vector<DocID> RestrictedCCDocs;
50+
llvm::StringMap<std::vector<DocID>> TypeDocs;
51+
llvm::StringMap<std::vector<DocID>> ScopeDocs;
52+
llvm::StringMap<std::vector<DocID>> ProximityDocs;
53+
std::vector<Trigram> TrigramScratch;
54+
55+
public:
56+
// Add the tokens which are given symbol's characteristics.
57+
// This includes fuzzy matching trigrams, symbol's scope, etc.
58+
// FIXME(kbobyrev): Support more token types:
59+
// * Namespace proximity
60+
void add(const Symbol &Sym, DocID D) {
61+
generateIdentifierTrigrams(Sym.Name, TrigramScratch);
62+
for (Trigram T : TrigramScratch)
63+
TrigramDocs[T].push_back(D);
64+
ScopeDocs[Sym.Scope].push_back(D);
65+
if (!llvm::StringRef(Sym.CanonicalDeclaration.FileURI).empty())
66+
for (const auto &ProximityURI :
67+
generateProximityURIs(Sym.CanonicalDeclaration.FileURI))
68+
ProximityDocs[ProximityURI].push_back(D);
69+
if (Sym.Flags & Symbol::IndexedForCodeCompletion)
70+
RestrictedCCDocs.push_back(D);
71+
if (!Sym.Type.empty())
72+
TypeDocs[Sym.Type].push_back(D);
73+
}
74+
75+
// Assemble the final compressed posting lists for the added symbols.
76+
llvm::DenseMap<Token, PostingList> build() {
77+
llvm::DenseMap<Token, PostingList> Result(/*InitialReserve=*/
78+
TrigramDocs.size() +
79+
RestrictedCCDocs.size() +
80+
TypeDocs.size() +
81+
ScopeDocs.size() +
82+
ProximityDocs.size());
83+
for (const auto &E : TrigramDocs)
84+
Result.try_emplace(Token(Token::Kind::Trigram, E.first.str()), E.second);
85+
for (const auto &E : TypeDocs)
86+
Result.try_emplace(Token(Token::Kind::Type, E.first()), E.second);
87+
for (const auto &E : ScopeDocs)
88+
Result.try_emplace(Token(Token::Kind::Scope, E.first()), E.second);
89+
for (const auto &E : ProximityDocs)
90+
Result.try_emplace(Token(Token::Kind::ProximityURI, E.first()), E.second);
91+
if (!RestrictedCCDocs.empty())
92+
Result.try_emplace(RestrictedForCodeCompletion, RestrictedCCDocs);
93+
return Result;
94+
}
95+
};
6496

6597
} // namespace
6698

@@ -86,18 +118,11 @@ void Dex::buildIndex() {
86118
Symbols[I] = ScoredSymbols[I].second;
87119
}
88120

89-
// Populate TempInvertedIndex with lists for index symbols.
90-
llvm::DenseMap<Token, std::vector<DocID>> TempInvertedIndex;
91-
for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) {
92-
const auto *Sym = Symbols[SymbolRank];
93-
for (const auto &Token : generateSearchTokens(*Sym))
94-
TempInvertedIndex[Token].push_back(SymbolRank);
95-
}
96-
97-
// Convert lists of items to posting lists.
98-
for (const auto &TokenToPostingList : TempInvertedIndex)
99-
InvertedIndex.insert(
100-
{TokenToPostingList.first, PostingList(TokenToPostingList.second)});
121+
// Build posting lists for symbols.
122+
IndexBuilder Builder;
123+
for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank)
124+
Builder.add(*Symbols[SymbolRank], SymbolRank);
125+
InvertedIndex = Builder.build();
101126
}
102127

103128
std::unique_ptr<Iterator> Dex::iterator(const Token &Tok) const {

clang-tools-extra/clangd/index/dex/Trigram.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Token.h"
1212
#include "llvm/ADT/ArrayRef.h"
1313
#include "llvm/ADT/DenseSet.h"
14+
#include "llvm/ADT/STLExtras.h"
1415
#include "llvm/ADT/StringExtras.h"
1516
#include <cctype>
1617
#include <queue>
@@ -20,7 +21,9 @@ namespace clang {
2021
namespace clangd {
2122
namespace dex {
2223

23-
std::vector<Token> generateIdentifierTrigrams(llvm::StringRef Identifier) {
24+
// Produce trigrams (including duplicates) and pass them to Out().
25+
template <typename Func>
26+
static void identifierTrigrams(llvm::StringRef Identifier, Func Out) {
2427
// Apply fuzzy matching text segmentation.
2528
std::vector<CharRole> Roles(Identifier.size());
2629
calculateRoles(Identifier,
@@ -46,12 +49,6 @@ std::vector<Token> generateIdentifierTrigrams(llvm::StringRef Identifier) {
4649
}
4750
}
4851

49-
llvm::DenseSet<Token> UniqueTrigrams;
50-
51-
auto Add = [&](std::string Chars) {
52-
UniqueTrigrams.insert(Token(Token::Kind::Trigram, Chars));
53-
};
54-
5552
// Iterate through valid sequences of three characters Fuzzy Matcher can
5653
// process.
5754
for (size_t I = 0; I < LowercaseIdentifier.size(); ++I) {
@@ -64,23 +61,41 @@ std::vector<Token> generateIdentifierTrigrams(llvm::StringRef Identifier) {
6461
for (const unsigned K : Next[J]) {
6562
if (K == 0)
6663
continue;
67-
Add({{LowercaseIdentifier[I], LowercaseIdentifier[J],
68-
LowercaseIdentifier[K]}});
64+
Out(Trigram(LowercaseIdentifier[I], LowercaseIdentifier[J],
65+
LowercaseIdentifier[K]));
6966
}
7067
}
7168
}
7269
// Emit short-query trigrams: FooBar -> f, fo, fb.
7370
if (!LowercaseIdentifier.empty())
74-
Add({LowercaseIdentifier[0]});
71+
Out(Trigram(LowercaseIdentifier[0]));
7572
if (LowercaseIdentifier.size() >= 2)
76-
Add({LowercaseIdentifier[0], LowercaseIdentifier[1]});
73+
Out(Trigram(LowercaseIdentifier[0], LowercaseIdentifier[1]));
7774
for (size_t I = 1; I < LowercaseIdentifier.size(); ++I)
7875
if (Roles[I] == Head) {
79-
Add({LowercaseIdentifier[0], LowercaseIdentifier[I]});
76+
Out(Trigram(LowercaseIdentifier[0], LowercaseIdentifier[I]));
8077
break;
8178
}
79+
}
8280

83-
return {UniqueTrigrams.begin(), UniqueTrigrams.end()};
81+
void generateIdentifierTrigrams(llvm::StringRef Identifier,
82+
std::vector<Trigram> &Result) {
83+
// Empirically, scanning for duplicates is faster with fewer trigrams, and
84+
// a hashtable is faster with more. This is a hot path, so dispatch based on
85+
// expected number of trigrams. Longer identifiers produce more trigrams.
86+
// The magic number was tuned by running IndexBenchmark.DexBuild.
87+
constexpr unsigned ManyTrigramsIdentifierThreshold = 14;
88+
Result.clear();
89+
if (Identifier.size() < ManyTrigramsIdentifierThreshold) {
90+
identifierTrigrams(Identifier, [&](Trigram T) {
91+
if (!llvm::is_contained(Result, T))
92+
Result.push_back(T);
93+
});
94+
} else {
95+
identifierTrigrams(Identifier, [&](Trigram T) { Result.push_back(T); });
96+
llvm::sort(Result);
97+
Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
98+
}
8499
}
85100

86101
std::vector<Token> generateQueryTrigrams(llvm::StringRef Query) {

0 commit comments

Comments
 (0)