Skip to content

Commit 5a9e93f

Browse files
committed
[clang][Driver] Improve multilib custom error reporting (#110804)
If `multilib.yaml` reports a custom error message for some unsupported configuration, it's not very helpful to display that error message _first_, and then follow it up with a huge list of all the multilib configurations that _are_ supported. In interactive use, the list is likely to scroll the most important message off the top of the user's window, leaving them with just a long list of available libraries, without a visible explanation of _why_ clang just printed that long list. Also, in general, it makes more intuitive sense to print the message last that shows why compilation can't continue, because that's where users are most likely to look for the reason why something stopped.
1 parent e0df221 commit 5a9e93f

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

clang/lib/Driver/Multilib.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags,
9999
llvm::SmallVectorImpl<Multilib> &Selected) const {
100100
llvm::StringSet<> FlagSet(expandFlags(Flags));
101101
Selected.clear();
102+
bool AnyErrors = false;
102103

103104
// Decide which multilibs we're going to select at all.
104105
llvm::DenseSet<StringRef> ExclusiveGroupsSelected;
@@ -123,12 +124,10 @@ bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags,
123124
}
124125

125126
// If this multilib is actually a placeholder containing an error message
126-
// written by the multilib.yaml author, display that error message, and
127-
// return failure.
128-
if (M.isError()) {
129-
D.Diag(clang::diag::err_drv_multilib_custom_error) << M.getErrorMessage();
130-
return false;
131-
}
127+
// written by the multilib.yaml author, then set a flag that will cause a
128+
// failure return. Our caller will display the error message.
129+
if (M.isError())
130+
AnyErrors = true;
132131

133132
// Select this multilib.
134133
Selected.push_back(M);
@@ -138,7 +137,7 @@ bool MultilibSet::select(const Driver &D, const Multilib::flags_list &Flags,
138137
// round.
139138
std::reverse(Selected.begin(), Selected.end());
140139

141-
return !Selected.empty();
140+
return !AnyErrors && !Selected.empty();
142141
}
143142

144143
llvm::StringSet<>

clang/lib/Driver/ToolChains/BareMetal.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,27 @@ static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D,
200200
return;
201201
D.Diag(clang::diag::warn_drv_missing_multilib) << llvm::join(Flags, " ");
202202
std::stringstream ss;
203+
204+
// If multilib selection didn't complete successfully, report a list
205+
// of all the configurations the user could have provided.
203206
for (const Multilib &Multilib : Result.Multilibs)
204207
if (!Multilib.isError())
205208
ss << "\n" << llvm::join(Multilib.flags(), " ");
206209
D.Diag(clang::diag::note_drv_available_multilibs) << ss.str();
210+
211+
// Now report any custom error messages requested by the YAML. We do
212+
// this after displaying the list of available multilibs, because
213+
// that list is probably large, and (in interactive use) risks
214+
// scrolling the useful error message off the top of the user's
215+
// terminal.
216+
for (const Multilib &Multilib : Result.SelectedMultilibs)
217+
if (Multilib.isError())
218+
D.Diag(clang::diag::err_drv_multilib_custom_error)
219+
<< Multilib.getErrorMessage();
220+
221+
// If there was an error, clear the SelectedMultilibs vector, in
222+
// case it contains partial data.
223+
Result.SelectedMultilibs.clear();
207224
}
208225

209226
static constexpr llvm::StringLiteral MultilibFilename = "multilib.yaml";

0 commit comments

Comments
 (0)