Skip to content

Commit 5c3c697

Browse files
author
Valery N Dmitriev
committed
Merge from 'master' to 'sycl-web' (intel#93)
CONFLICT (modify/delete): clang/include/clang/Driver/CC1Options.td deleted in 3607aac and modified in HEAD. Version HEAD of clang/include/clang/Driver/CC1Options.td left in tree.
2 parents 1bd6d75 + 3607aac commit 5c3c697

File tree

268 files changed

+7624
-3043
lines changed

Some content is hidden

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

268 files changed

+7624
-3043
lines changed

clang-tools-extra/clang-tidy/ClangTidyCheck.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,25 @@ ClangTidyCheck::OptionsView::get(StringRef LocalName) const {
7676
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
7777
}
7878

79+
static ClangTidyOptions::OptionMap::const_iterator
80+
findPriorityOption(const ClangTidyOptions::OptionMap &Options, StringRef NamePrefix,
81+
StringRef LocalName) {
82+
auto IterLocal = Options.find((NamePrefix + LocalName).str());
83+
auto IterGlobal = Options.find(LocalName.str());
84+
if (IterLocal == Options.end())
85+
return IterGlobal;
86+
if (IterGlobal == Options.end())
87+
return IterLocal;
88+
if (IterLocal->second.Priority >= IterGlobal->second.Priority)
89+
return IterLocal;
90+
return IterGlobal;
91+
}
92+
7993
llvm::Expected<std::string>
8094
ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const {
81-
auto IterLocal = CheckOptions.find(NamePrefix + LocalName.str());
82-
auto IterGlobal = CheckOptions.find(LocalName.str());
83-
if (IterLocal != CheckOptions.end() &&
84-
(IterGlobal == CheckOptions.end() ||
85-
IterLocal->second.Priority >= IterGlobal->second.Priority))
86-
return IterLocal->second.Value;
87-
if (IterGlobal != CheckOptions.end())
88-
return IterGlobal->second.Value;
95+
auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName);
96+
if (Iter != CheckOptions.end())
97+
return Iter->second.Value;
8998
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
9099
}
91100

@@ -124,14 +133,9 @@ bool ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName,
124133
template <>
125134
llvm::Expected<bool>
126135
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const {
127-
auto IterLocal = CheckOptions.find(NamePrefix + LocalName.str());
128-
auto IterGlobal = CheckOptions.find(LocalName.str());
129-
if (IterLocal != CheckOptions.end() &&
130-
(IterGlobal == CheckOptions.end() ||
131-
IterLocal->second.Priority >= IterGlobal->second.Priority))
132-
return getAsBool(IterLocal->second.Value, NamePrefix + LocalName);
133-
if (IterGlobal != CheckOptions.end())
134-
return getAsBool(IterGlobal->second.Value, llvm::Twine(LocalName));
136+
auto Iter = findPriorityOption(CheckOptions, NamePrefix, LocalName);
137+
if (Iter != CheckOptions.end())
138+
return getAsBool(Iter->second.Value, Iter->first);
135139
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
136140
}
137141

@@ -160,9 +164,8 @@ void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
160164
llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
161165
StringRef LocalName, ArrayRef<std::pair<StringRef, int64_t>> Mapping,
162166
bool CheckGlobal, bool IgnoreCase) {
163-
auto Iter = CheckOptions.find((NamePrefix + LocalName).str());
164-
if (CheckGlobal && Iter == CheckOptions.end())
165-
Iter = CheckOptions.find(LocalName.str());
167+
auto Iter = CheckGlobal ? findPriorityOption(CheckOptions, NamePrefix, LocalName)
168+
: CheckOptions.find((NamePrefix + LocalName).str());
166169
if (Iter == CheckOptions.end())
167170
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
168171

clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@ namespace tidy {
2020
namespace bugprone {
2121

2222
void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) {
23-
// Note: void *memset(void *buffer, int fill_char, size_t byte_count);
23+
// Match the standard memset:
24+
// void *memset(void *buffer, int fill_char, size_t byte_count);
25+
auto MemsetDecl =
26+
functionDecl(hasName("::memset"),
27+
parameterCountIs(3),
28+
hasParameter(0, hasType(pointerType(pointee(voidType())))),
29+
hasParameter(1, hasType(isInteger())),
30+
hasParameter(2, hasType(isInteger())));
31+
2432
// Look for memset(x, '0', z). Probably memset(x, 0, z) was intended.
2533
Finder->addMatcher(
2634
callExpr(
27-
callee(functionDecl(hasName("::memset"))),
35+
callee(MemsetDecl),
2836
hasArgument(1, characterLiteral(equals(static_cast<unsigned>('0')))
2937
.bind("char-zero-fill")),
3038
unless(
@@ -36,14 +44,14 @@ void SuspiciousMemsetUsageCheck::registerMatchers(MatchFinder *Finder) {
3644

3745
// Look for memset with an integer literal in its fill_char argument.
3846
// Will check if it gets truncated.
39-
Finder->addMatcher(callExpr(callee(functionDecl(hasName("::memset"))),
47+
Finder->addMatcher(callExpr(callee(MemsetDecl),
4048
hasArgument(1, integerLiteral().bind("num-fill")),
4149
unless(isInTemplateInstantiation())),
4250
this);
4351

4452
// Look for memset(x, y, 0) as that is most likely an argument swap.
4553
Finder->addMatcher(
46-
callExpr(callee(functionDecl(hasName("::memset"))),
54+
callExpr(callee(MemsetDecl),
4755
unless(hasArgument(1, anyOf(characterLiteral(equals(
4856
static_cast<unsigned>('0'))),
4957
integerLiteral()))),

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
599599
}},
600600
{"semanticTokensProvider",
601601
llvm::json::Object{
602-
{"documentProvider", llvm::json::Object{{"edits", true}}},
603-
{"rangeProvider", false},
602+
{"full", llvm::json::Object{{"delta", true}}},
603+
{"range", false},
604604
{"legend",
605605
llvm::json::Object{{"tokenTypes", semanticTokenTypes()},
606606
{"tokenModifiers", llvm::json::Array()}}},
@@ -1311,9 +1311,9 @@ void ClangdLSPServer::onSemanticTokens(const SemanticTokensParams &Params,
13111311
});
13121312
}
13131313

1314-
void ClangdLSPServer::onSemanticTokensEdits(
1315-
const SemanticTokensEditsParams &Params,
1316-
Callback<SemanticTokensOrEdits> CB) {
1314+
void ClangdLSPServer::onSemanticTokensDelta(
1315+
const SemanticTokensDeltaParams &Params,
1316+
Callback<SemanticTokensOrDelta> CB) {
13171317
Server->semanticHighlights(
13181318
Params.textDocument.uri.file(),
13191319
[this, PrevResultID(Params.previousResultId),
@@ -1323,16 +1323,16 @@ void ClangdLSPServer::onSemanticTokensEdits(
13231323
return CB(HT.takeError());
13241324
std::vector<SemanticToken> Toks = toSemanticTokens(*HT);
13251325

1326-
SemanticTokensOrEdits Result;
1326+
SemanticTokensOrDelta Result;
13271327
{
13281328
std::lock_guard<std::mutex> Lock(SemanticTokensMutex);
13291329
auto &Last = LastSemanticTokens[File];
13301330

13311331
if (PrevResultID == Last.resultId) {
13321332
Result.edits = diffTokens(Last.tokens, Toks);
13331333
} else {
1334-
vlog("semanticTokens/edits: wanted edits vs {0} but last result "
1335-
"had ID {1}. Returning full token list.",
1334+
vlog("semanticTokens/full/delta: wanted edits vs {0} but last "
1335+
"result had ID {1}. Returning full token list.",
13361336
PrevResultID, Last.resultId);
13371337
Result.tokens = Toks;
13381338
}
@@ -1393,8 +1393,8 @@ ClangdLSPServer::ClangdLSPServer(
13931393
MsgHandler->bind("typeHierarchy/resolve", &ClangdLSPServer::onResolveTypeHierarchy);
13941394
MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange);
13951395
MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink);
1396-
MsgHandler->bind("textDocument/semanticTokens", &ClangdLSPServer::onSemanticTokens);
1397-
MsgHandler->bind("textDocument/semanticTokens/edits", &ClangdLSPServer::onSemanticTokensEdits);
1396+
MsgHandler->bind("textDocument/semanticTokens/full", &ClangdLSPServer::onSemanticTokens);
1397+
MsgHandler->bind("textDocument/semanticTokens/full/delta", &ClangdLSPServer::onSemanticTokensDelta);
13981398
// clang-format on
13991399
}
14001400

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
121121
void onDocumentLink(const DocumentLinkParams &,
122122
Callback<std::vector<DocumentLink>>);
123123
void onSemanticTokens(const SemanticTokensParams &, Callback<SemanticTokens>);
124-
void onSemanticTokensEdits(const SemanticTokensEditsParams &,
125-
Callback<SemanticTokensOrEdits>);
124+
void onSemanticTokensDelta(const SemanticTokensDeltaParams &,
125+
Callback<SemanticTokensOrDelta>);
126126

127127
std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);
128128

clang-tools-extra/clangd/ConfigCompile.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,22 @@ struct FragmentCompiler {
103103
});
104104
});
105105
}
106+
107+
auto PathExclude = std::make_unique<std::vector<llvm::Regex>>();
108+
for (auto &Entry : F.PathExclude) {
109+
if (auto RE = compileRegex(Entry))
110+
PathExclude->push_back(std::move(*RE));
111+
}
112+
if (!PathExclude->empty()) {
113+
Out.Conditions.push_back(
114+
[PathExclude(std::move(PathExclude))](const Params &P) {
115+
if (P.Path.empty())
116+
return false;
117+
return llvm::none_of(*PathExclude, [&](const llvm::Regex &RE) {
118+
return RE.match(P.Path);
119+
});
120+
});
121+
}
106122
}
107123

108124
void compile(Fragment::CompileFlagsBlock &&F) {

clang-tools-extra/clangd/ConfigFragment.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ struct Fragment {
108108
struct IfBlock {
109109
/// The file being processed must fully match a regular expression.
110110
std::vector<Located<std::string>> PathMatch;
111+
/// The file being processed must *not* fully match a regular expression.
112+
std::vector<Located<std::string>> PathExclude;
113+
111114
/// An unrecognized key was found while parsing the condition.
112115
/// The condition will evaluate to false.
113116
bool HasUnrecognizedCondition = false;

clang-tools-extra/clangd/ConfigYAML.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class Parser {
5050
if (auto Values = scalarValues(N))
5151
F.PathMatch = std::move(*Values);
5252
});
53+
Dict.handle("PathExclude", [&](Node &N) {
54+
if (auto Values = scalarValues(N))
55+
F.PathExclude = std::move(*Values);
56+
});
5357
Dict.parse(N);
5458
}
5559

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ nodeToString(const ast_type_traits::DynTypedNode &N) {
5858
return S;
5959
}
6060

61+
// Helper function for getMembersReferencedViaDependentName()
62+
// which takes a dependent type `T` and heuristically
63+
// resolves it to a CXXRecordDecl in which we can try name lookup.
64+
CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) {
65+
assert(T);
66+
if (const auto *ICNT = T->getAs<InjectedClassNameType>()) {
67+
T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
68+
}
69+
const auto *TST = T->getAs<TemplateSpecializationType>();
70+
if (!TST)
71+
return nullptr;
72+
const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
73+
TST->getTemplateName().getAsTemplateDecl());
74+
if (!TD)
75+
return nullptr;
76+
return TD->getTemplatedDecl();
77+
}
78+
6179
// Given a dependent type and a member name, heuristically resolve the
6280
// name to one or more declarations.
6381
// The current heuristic is simply to look up the name in the primary
@@ -82,25 +100,17 @@ std::vector<const NamedDecl *> getMembersReferencedViaDependentName(
82100
ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext()));
83101
return {Result.begin(), Result.end()};
84102
}
85-
if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
86-
T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
103+
if (auto *RD = resolveTypeToRecordDecl(T)) {
104+
if (!RD->hasDefinition())
105+
return {};
106+
RD = RD->getDefinition();
107+
DeclarationName Name = NameFactory(RD->getASTContext());
108+
return RD->lookupDependentName(Name, [=](const NamedDecl *D) {
109+
return IsNonstaticMember ? D->isCXXInstanceMember()
110+
: !D->isCXXInstanceMember();
111+
});
87112
}
88-
auto *TST = T->getAs<TemplateSpecializationType>();
89-
if (!TST)
90-
return {};
91-
const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
92-
TST->getTemplateName().getAsTemplateDecl());
93-
if (!TD)
94-
return {};
95-
CXXRecordDecl *RD = TD->getTemplatedDecl();
96-
if (!RD->hasDefinition())
97-
return {};
98-
RD = RD->getDefinition();
99-
DeclarationName Name = NameFactory(RD->getASTContext());
100-
return RD->lookupDependentName(Name, [=](const NamedDecl *D) {
101-
return IsNonstaticMember ? D->isCXXInstanceMember()
102-
: !D->isCXXInstanceMember();
103-
});
113+
return {};
104114
}
105115

106116
// Given the type T of a dependent expression that appears of the LHS of a "->",
@@ -144,6 +154,28 @@ const Type *getPointeeType(const Type *T) {
144154
return FirstArg.getAsType().getTypePtrOrNull();
145155
}
146156

157+
// Try to heuristically resolve a dependent expression `E` to one
158+
// or more declarations that it likely references.
159+
std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
160+
assert(E->isTypeDependent());
161+
if (const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(E)) {
162+
const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
163+
if (ME->isArrow()) {
164+
BaseType = getPointeeType(BaseType);
165+
}
166+
return getMembersReferencedViaDependentName(
167+
BaseType, [ME](ASTContext &) { return ME->getMember(); },
168+
/*IsNonstaticMember=*/true);
169+
}
170+
if (const auto *RE = dyn_cast<DependentScopeDeclRefExpr>(E)) {
171+
return getMembersReferencedViaDependentName(
172+
RE->getQualifier()->getAsType(),
173+
[RE](ASTContext &) { return RE->getDeclName(); },
174+
/*IsNonstaticMember=*/false);
175+
}
176+
return {};
177+
}
178+
147179
const NamedDecl *getTemplatePattern(const NamedDecl *D) {
148180
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
149181
if (const auto *Result = CRD->getTemplateInstantiationPattern())
@@ -341,21 +373,12 @@ struct TargetFinder {
341373
}
342374
void
343375
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
344-
const Type *BaseType = E->getBaseType().getTypePtrOrNull();
345-
if (E->isArrow()) {
346-
BaseType = getPointeeType(BaseType);
347-
}
348-
for (const NamedDecl *D : getMembersReferencedViaDependentName(
349-
BaseType, [E](ASTContext &) { return E->getMember(); },
350-
/*IsNonstaticMember=*/true)) {
376+
for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
351377
Outer.add(D, Flags);
352378
}
353379
}
354380
void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
355-
for (const NamedDecl *D : getMembersReferencedViaDependentName(
356-
E->getQualifier()->getAsType(),
357-
[E](ASTContext &) { return E->getDeclName(); },
358-
/*IsNonstaticMember=*/false)) {
381+
for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
359382
Outer.add(D, Flags);
360383
}
361384
}

clang-tools-extra/clangd/Hover.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,23 @@ void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
329329

330330
llvm::Optional<std::string> printExprValue(const Expr *E,
331331
const ASTContext &Ctx) {
332-
Expr::EvalResult Constant;
332+
// InitListExpr has two forms, syntactic and semantic. They are the same thing
333+
// (refer to a same AST node) in most cases.
334+
// When they are different, RAV returns the syntactic form, and we should feed
335+
// the semantic form to EvaluateAsRValue.
336+
if (const auto *ILE = llvm::dyn_cast<InitListExpr>(E)) {
337+
if (!ILE->isSemanticForm())
338+
E = ILE->getSemanticForm();
339+
}
340+
333341
// Evaluating [[foo]]() as "&foo" isn't useful, and prevents us walking up
334342
// to the enclosing call.
335343
QualType T = E->getType();
336344
if (T.isNull() || T->isFunctionType() || T->isFunctionPointerType() ||
337345
T->isFunctionReferenceType())
338346
return llvm::None;
347+
348+
Expr::EvalResult Constant;
339349
// Attempt to evaluate. If expr is dependent, evaluation crashes!
340350
if (E->isValueDependent() || !E->EvaluateAsRValue(Constant, Ctx) ||
341351
// Disable printing for record-types, as they are usually confusing and

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ llvm::json::Value toJSON(const SemanticTokensEdit &Edit) {
10291029
{"data", encodeTokens(Edit.tokens)}};
10301030
}
10311031

1032-
llvm::json::Value toJSON(const SemanticTokensOrEdits &TE) {
1032+
llvm::json::Value toJSON(const SemanticTokensOrDelta &TE) {
10331033
llvm::json::Object Result{{"resultId", TE.resultId}};
10341034
if (TE.edits)
10351035
Result["edits"] = *TE.edits;
@@ -1043,7 +1043,7 @@ bool fromJSON(const llvm::json::Value &Params, SemanticTokensParams &R) {
10431043
return O && O.map("textDocument", R.textDocument);
10441044
}
10451045

1046-
bool fromJSON(const llvm::json::Value &Params, SemanticTokensEditsParams &R) {
1046+
bool fromJSON(const llvm::json::Value &Params, SemanticTokensDeltaParams &R) {
10471047
llvm::json::ObjectMapper O(Params);
10481048
return O && O.map("textDocument", R.textDocument) &&
10491049
O.map("previousResultId", R.previousResultId);

0 commit comments

Comments
 (0)