118class MessageFormattedText {
120 template <
typename... A>
122 : severity_{text.severity()} {
123 Format(&text, Convert(std::forward<A>(x))...);
125 MessageFormattedText(
const MessageFormattedText &) =
default;
126 MessageFormattedText(MessageFormattedText &&) =
default;
127 MessageFormattedText &operator=(
const MessageFormattedText &) =
default;
128 MessageFormattedText &operator=(MessageFormattedText &&) =
default;
129 const std::string &string()
const {
return string_; }
130 bool IsFatal()
const {
return IsFatalSeverity(severity_); }
131 Severity severity()
const {
return severity_; }
132 MessageFormattedText &set_severity(Severity severity) {
133 severity_ = severity;
136 std::string MoveString() {
return std::move(string_); }
137 bool operator==(
const MessageFormattedText &that)
const {
138 return severity_ == that.severity_ && string_ == that.string_;
140 bool operator!=(
const MessageFormattedText &that)
const {
141 return !(*
this == that);
147 template <
typename A> A Convert(
const A &x) {
148 static_assert(!std::is_class_v<std::decay_t<A>>);
151 template <
typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
152 static_assert(!std::is_class_v<std::decay_t<A>>);
155 const char *Convert(
const char *s) {
return s; }
156 const char *Convert(
char *s) {
return s; }
157 const char *Convert(
const std::string &);
158 const char *Convert(std::string &&);
159 const char *Convert(
const std::string_view &);
160 const char *Convert(std::string_view &&);
162 std::intmax_t Convert(std::int64_t x) {
return x; }
163 std::uintmax_t Convert(std::uint64_t x) {
return x; }
167 std::forward_list<std::string> conversions_;
204 Message(
const Message &) =
default;
205 Message(Message &&) =
default;
206 Message &operator=(
const Message &) =
default;
207 Message &operator=(Message &&) =
default;
210 : location_{pr}, text_{t} {}
212 : location_{pr}, text_{s} {}
214 : location_{pr}, text_{std::move(s)} {}
216 : location_{pr}, text_{t} {}
218 Message(common::LanguageFeature feature, ProvenanceRange pr,
220 : location_{pr}, text_{t}, languageFeature_{feature} {}
221 Message(common::LanguageFeature feature, ProvenanceRange pr,
223 : location_{pr}, text_{s}, languageFeature_{feature} {}
224 Message(common::LanguageFeature feature, ProvenanceRange pr,
226 : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
228 Message(common::UsageWarning warning, ProvenanceRange pr,
230 : location_{pr}, text_{t}, usageWarning_{warning} {}
231 Message(common::UsageWarning warning, ProvenanceRange pr,
233 : location_{pr}, text_{s}, usageWarning_{warning} {}
234 Message(common::UsageWarning warning, ProvenanceRange pr,
236 : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
239 : location_{csr}, text_{t} {}
241 : location_{csr}, text_{s} {}
243 : location_{csr}, text_{std::move(s)} {}
245 : location_{csr}, text_{t} {}
249 : location_{csr}, text_{t}, languageFeature_{feature} {}
250 Message(common::LanguageFeature feature,
CharBlock csr,
252 : location_{csr}, text_{s}, languageFeature_{feature} {}
255 : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
259 : location_{csr}, text_{t}, usageWarning_{warning} {}
260 Message(common::UsageWarning warning,
CharBlock csr,
262 : location_{csr}, text_{s}, usageWarning_{warning} {}
264 : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
266 template <
typename RANGE,
typename A,
typename... As>
269 t, std::forward<A>(x), std::forward<As>(xs)...}} {}
270 template <
typename RANGE,
typename A,
typename... As>
271 Message(common::LanguageFeature feature, RANGE r,
const MessageFixedText &t,
274 t, std::forward<A>(x), std::forward<As>(xs)...}},
275 languageFeature_{feature} {}
276 template <
typename RANGE,
typename A,
typename... As>
280 t, std::forward<A>(x), std::forward<As>(xs)...}},
281 usageWarning_{warning} {}
283 Reference attachment()
const {
return attachment_; }
285 void SetContext(Message *c) {
287 attachmentIsContext_ =
true;
289 Message &Attach(Message *);
290 Message &Attach(std::unique_ptr<Message> &&);
291 template <
typename... A> Message &Attach(A &&...args) {
292 return Attach(
new Message{std::forward<A>(args)...});
295 bool SortBefore(
const Message &that)
const;
296 bool IsFatal()
const;
297 Severity severity()
const;
298 Message &set_severity(Severity);
299 std::optional<common::LanguageFeature> languageFeature()
const;
300 Message &set_languageFeature(common::LanguageFeature);
301 std::optional<common::UsageWarning> usageWarning()
const;
302 Message &set_usageWarning(common::UsageWarning);
303 std::string ToString()
const;
304 std::optional<ProvenanceRange> GetProvenanceRange(
307 bool echoSourceLine =
true,
314 bool IsMergeable()
const {
315 return std::holds_alternative<MessageExpectedText>(text_);
317 bool Merge(
const Message &);
318 bool operator==(
const Message &that)
const;
319 bool operator!=(
const Message &that)
const {
return !(*
this == that); }
320 bool AtSameLocation(
const Message &)
const;
323 std::variant<ProvenanceRange, CharBlock> location_;
324 std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
326 bool attachmentIsContext_{
false};
327 Reference attachment_;
328 std::optional<common::LanguageFeature> languageFeature_;
329 std::optional<common::UsageWarning> usageWarning_;
335 Messages(Messages &&that) : messages_{std::move(that.messages_)} {}
336 Messages &operator=(Messages &&that) {
337 messages_ = std::move(that.messages_);
341 std::list<Message> &messages() {
return messages_; }
342 bool empty()
const {
return messages_.empty(); }
343 void clear() { messages_.clear(); }
345 template <
typename... A>
Message &Say(A &&...args) {
346 return messages_.emplace_back(std::forward<A>(args)...);
349 template <
typename... A>
350 Message *Warn(
bool isInModuleFile,
352 common::LanguageFeature feature, A &&...args) {
353 if (!isInModuleFile && control.ShouldWarn(feature)) {
354 return &AddWarning(feature, std::forward<A>(args)...);
359 template <
typename... A>
360 Message *Warn(
bool isInModuleFile,
362 common::UsageWarning warning, A &&...args) {
363 if (!isInModuleFile && control.ShouldWarn(warning)) {
364 return &AddWarning(warning, std::forward<A>(args)...);
369 void Annex(Messages &&that) {
370 messages_.splice(messages_.end(), that.messages_);
374 void Merge(Messages &&);
375 void Copy(
const Messages &);
378 bool echoSourceLines =
true,
380 std::size_t maxErrorsToEmit = 0,
bool warningsAreErrors =
false)
const;
381 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
382 bool AnyFatalError(
bool warningsAreErrors =
false)
const;
385 template <
typename... A>
386 Message &AddWarning(common::UsageWarning warning, A &&...args) {
387 return messages_.emplace_back(warning, std::forward<A>(args)...);
389 template <
typename... A>
390 Message &AddWarning(common::LanguageFeature feature, A &&...args) {
391 return messages_.emplace_back(feature, std::forward<A>(args)...);
393 std::list<Message> messages_;
396class ContextualMessages {
398 ContextualMessages() =
default;
400 explicit ContextualMessages(
Messages *m) : messages_{m} {}
401 ContextualMessages(
const ContextualMessages &that)
402 : at_{that.at_}, messages_{that.messages_} {}
405 Messages *messages()
const {
return messages_; }
406 Message::Reference contextMessage()
const {
return contextMessage_; }
407 bool empty()
const {
return !messages_ || messages_->empty(); }
414 return common::ScopedSet(at_, std::move(at));
419 m = contextMessage_.get();
421 return common::ScopedSet(contextMessage_, m);
427 return common::ScopedSet(messages_, &buffer);
431 return common::ScopedSet(messages_,
nullptr);
434 template <
typename... A>
Message *Say(A &&...args) {
435 return Say(at_, std::forward<A>(args)...);
439 if (messages_ !=
nullptr) {
440 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
441 if (contextMessage_) {
442 msg.SetContext(contextMessage_.get());
450 template <
typename... A>
451 Message *Say(std::optional<CharBlock> at, A &&...args) {
452 return Say(at.value_or(at_), std::forward<A>(args)...);
456 if (messages_ !=
nullptr) {
457 if (contextMessage_) {
458 msg.SetContext(contextMessage_.get());
460 return &messages_->Say(std::move(msg));
466 template <
typename FeatureOrUsageWarning,
typename... A>
467 Message *Warn(
bool isInModuleFile,
469 FeatureOrUsageWarning feature,
CharBlock at, A &&...args) {
470 if (messages_ !=
nullptr) {
472 msg{messages_->Warn(isInModuleFile, control, feature, at,
473 std::forward<A>(args)...)}) {
474 if (contextMessage_) {
475 msg->SetContext(contextMessage_.get());
483 template <
typename FeatureOrUsageWarning,
typename... A>
484 Message *Warn(
bool isInModuleFile,
486 FeatureOrUsageWarning feature, A &&...args) {
488 isInModuleFile, control, feature, at_, std::forward<A>(args)...);
491 template <
typename FeatureOrUsageWarning,
typename... A>
492 Message *Warn(
bool isInModuleFile,
494 FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
495 return Warn(isInModuleFile, control, feature, at.value_or(at_),
496 std::forward<A>(args)...);
502 Message::Reference contextMessage_;