Skip to content

Commit c40f925

Browse files
author
iclsrc
committed
Merge from 'master' to 'sycl-web' (intel#36)
CONFLICT (modify/delete): llvm/test/tools/llvm-profdata/show-prof-size.test deleted in e3ba652 and modified in HEAD. Version HEAD of llvm/test/tools/llvm-profdata/show-prof-size.test left in tree.
2 parents ebdffb7 + e3ba652 commit c40f925

File tree

225 files changed

+3955
-1797
lines changed

Some content is hidden

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

225 files changed

+3955
-1797
lines changed

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

Lines changed: 142 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,44 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "ClangTidyCheck.h"
10+
#include "llvm/ADT/SmallString.h"
11+
#include "llvm/ADT/StringRef.h"
12+
#include "llvm/Support/Error.h"
13+
#include "llvm/Support/raw_ostream.h"
1014

1115
namespace clang {
1216
namespace tidy {
1317

18+
char MissingOptionError::ID;
19+
char UnparseableEnumOptionError::ID;
20+
char UnparseableIntegerOptionError::ID;
21+
22+
std::string MissingOptionError::message() const {
23+
llvm::SmallString<128> Buffer;
24+
llvm::raw_svector_ostream Output(Buffer);
25+
Output << "option not found '" << OptionName << '\'';
26+
return std::string(Buffer);
27+
}
28+
29+
std::string UnparseableEnumOptionError::message() const {
30+
llvm::SmallString<128> Buffer;
31+
llvm::raw_svector_ostream Output(Buffer);
32+
Output << "invalid configuration value '" << LookupValue << "' for option '"
33+
<< LookupName << '\'';
34+
if (SuggestedValue)
35+
Output << "; did you mean '" << *SuggestedValue << "'?";
36+
return std::string(Buffer);
37+
}
38+
39+
std::string UnparseableIntegerOptionError::message() const {
40+
llvm::SmallString<128> Buffer;
41+
llvm::raw_svector_ostream Output(Buffer);
42+
Output << "invalid configuration value '" << LookupValue << "' for option '"
43+
<< LookupName << "'; expected "
44+
<< (IsBoolean ? "a bool" : "an integer value");
45+
return std::string(Buffer);
46+
}
47+
1448
ClangTidyCheck::ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
1549
: CheckName(CheckName), Context(Context),
1650
Options(CheckName, Context->getOptions().CheckOptions) {
@@ -34,25 +68,82 @@ ClangTidyCheck::OptionsView::OptionsView(StringRef CheckName,
3468
const ClangTidyOptions::OptionMap &CheckOptions)
3569
: NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
3670

37-
std::string ClangTidyCheck::OptionsView::get(StringRef LocalName,
38-
StringRef Default) const {
71+
llvm::Expected<std::string>
72+
ClangTidyCheck::OptionsView::get(StringRef LocalName) const {
3973
const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
4074
if (Iter != CheckOptions.end())
4175
return Iter->second;
42-
return std::string(Default);
76+
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
4377
}
4478

45-
std::string
46-
ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName,
47-
StringRef Default) const {
79+
llvm::Expected<std::string>
80+
ClangTidyCheck::OptionsView::getLocalOrGlobal(StringRef LocalName) const {
4881
auto Iter = CheckOptions.find(NamePrefix + LocalName.str());
4982
if (Iter != CheckOptions.end())
5083
return Iter->second;
5184
// Fallback to global setting, if present.
5285
Iter = CheckOptions.find(LocalName.str());
5386
if (Iter != CheckOptions.end())
5487
return Iter->second;
55-
return std::string(Default);
88+
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
89+
}
90+
91+
static llvm::Expected<bool> getAsBool(StringRef Value,
92+
const llvm::Twine &LookupName) {
93+
if (Value == "true")
94+
return true;
95+
if (Value == "false")
96+
return false;
97+
bool Result;
98+
if (!Value.getAsInteger(10, Result))
99+
return Result;
100+
return llvm::make_error<UnparseableIntegerOptionError>(LookupName.str(),
101+
Value.str(), true);
102+
}
103+
104+
template <>
105+
llvm::Expected<bool>
106+
ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName) const {
107+
llvm::Expected<std::string> ValueOr = get(LocalName);
108+
if (ValueOr)
109+
return getAsBool(*ValueOr, NamePrefix + LocalName);
110+
return ValueOr.takeError();
111+
}
112+
113+
template <>
114+
bool ClangTidyCheck::OptionsView::get<bool>(StringRef LocalName,
115+
bool Default) const {
116+
llvm::Expected<bool> ValueOr = get<bool>(LocalName);
117+
if (ValueOr)
118+
return *ValueOr;
119+
logErrToStdErr(ValueOr.takeError());
120+
return Default;
121+
}
122+
123+
template <>
124+
llvm::Expected<bool>
125+
ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName) const {
126+
llvm::Expected<std::string> ValueOr = get(LocalName);
127+
bool IsGlobal = false;
128+
if (!ValueOr) {
129+
llvm::consumeError(ValueOr.takeError());
130+
ValueOr = getLocalOrGlobal(LocalName);
131+
IsGlobal = true;
132+
}
133+
if (!ValueOr)
134+
return ValueOr.takeError();
135+
return getAsBool(*ValueOr, IsGlobal ? llvm::Twine(LocalName)
136+
: (NamePrefix + LocalName));
137+
}
138+
139+
template <>
140+
bool ClangTidyCheck::OptionsView::getLocalOrGlobal<bool>(StringRef LocalName,
141+
bool Default) const {
142+
llvm::Expected<bool> ValueOr = getLocalOrGlobal<bool>(LocalName);
143+
if (ValueOr)
144+
return *ValueOr;
145+
logErrToStdErr(ValueOr.takeError());
146+
return Default;
56147
}
57148

58149
void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
@@ -67,5 +158,49 @@ void ClangTidyCheck::OptionsView::store(ClangTidyOptions::OptionMap &Options,
67158
store(Options, LocalName, llvm::itostr(Value));
68159
}
69160

161+
llvm::Expected<int64_t> ClangTidyCheck::OptionsView::getEnumInt(
162+
StringRef LocalName, ArrayRef<std::pair<StringRef, int64_t>> Mapping,
163+
bool CheckGlobal, bool IgnoreCase) {
164+
auto Iter = CheckOptions.find((NamePrefix + LocalName).str());
165+
if (CheckGlobal && Iter == CheckOptions.end())
166+
Iter = CheckOptions.find(LocalName.str());
167+
if (Iter == CheckOptions.end())
168+
return llvm::make_error<MissingOptionError>((NamePrefix + LocalName).str());
169+
170+
StringRef Value = Iter->second;
171+
StringRef Closest;
172+
unsigned EditDistance = -1;
173+
for (const auto &NameAndEnum : Mapping) {
174+
if (IgnoreCase) {
175+
if (Value.equals_lower(NameAndEnum.first))
176+
return NameAndEnum.second;
177+
} else if (Value.equals(NameAndEnum.first)) {
178+
return NameAndEnum.second;
179+
} else if (Value.equals_lower(NameAndEnum.first)) {
180+
Closest = NameAndEnum.first;
181+
EditDistance = 0;
182+
continue;
183+
}
184+
unsigned Distance = Value.edit_distance(NameAndEnum.first);
185+
if (Distance < EditDistance) {
186+
EditDistance = Distance;
187+
Closest = NameAndEnum.first;
188+
}
189+
}
190+
if (EditDistance < 3)
191+
return llvm::make_error<UnparseableEnumOptionError>(
192+
Iter->first, Iter->second, std::string(Closest));
193+
return llvm::make_error<UnparseableEnumOptionError>(Iter->first,
194+
Iter->second);
195+
}
196+
197+
void ClangTidyCheck::OptionsView::logErrToStdErr(llvm::Error &&Err) {
198+
llvm::logAllUnhandledErrors(
199+
llvm::handleErrors(std::move(Err),
200+
[](const MissingOptionError &) -> llvm::Error {
201+
return llvm::Error::success();
202+
}),
203+
llvm::errs(), "warning: ");
204+
}
70205
} // namespace tidy
71206
} // namespace clang

0 commit comments

Comments
 (0)