104class MessageFormattedText {
106 template <
typename... A>
108 : severity_{text.severity()} {
109 Format(&text, Convert(std::forward<A>(x))...);
111 MessageFormattedText(
const MessageFormattedText &) =
default;
112 MessageFormattedText(MessageFormattedText &&) =
default;
113 MessageFormattedText &operator=(
const MessageFormattedText &) =
default;
114 MessageFormattedText &operator=(MessageFormattedText &&) =
default;
115 const std::string &string()
const {
return string_; }
116 bool IsFatal()
const {
117 return severity_ == Severity::Error || severity_ == Severity::Todo;
119 Severity severity()
const {
return severity_; }
120 MessageFormattedText &set_severity(Severity severity) {
121 severity_ = severity;
124 std::string MoveString() {
return std::move(string_); }
125 bool operator==(
const MessageFormattedText &that)
const {
126 return severity_ == that.severity_ && string_ == that.string_;
128 bool operator!=(
const MessageFormattedText &that)
const {
129 return !(*
this == that);
135 template <
typename A> A Convert(
const A &x) {
136 static_assert(!std::is_class_v<std::decay_t<A>>);
139 template <
typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
140 static_assert(!std::is_class_v<std::decay_t<A>>);
143 const char *Convert(
const char *s) {
return s; }
144 const char *Convert(
char *s) {
return s; }
145 const char *Convert(
const std::string &);
146 const char *Convert(std::string &&);
147 const char *Convert(
const std::string_view &);
148 const char *Convert(std::string_view &&);
150 std::intmax_t Convert(std::int64_t x) {
return x; }
151 std::uintmax_t Convert(std::uint64_t x) {
return x; }
155 std::forward_list<std::string> conversions_;
192 Message(
const Message &) =
default;
193 Message(Message &&) =
default;
194 Message &operator=(
const Message &) =
default;
195 Message &operator=(Message &&) =
default;
198 : location_{pr}, text_{t} {}
200 : location_{pr}, text_{s} {}
202 : location_{pr}, text_{std::move(s)} {}
204 : location_{pr}, text_{t} {}
206 Message(common::LanguageFeature feature, ProvenanceRange pr,
208 : location_{pr}, text_{t}, languageFeature_{feature} {}
209 Message(common::LanguageFeature feature, ProvenanceRange pr,
211 : location_{pr}, text_{s}, languageFeature_{feature} {}
212 Message(common::LanguageFeature feature, ProvenanceRange pr,
214 : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
216 Message(common::UsageWarning warning, ProvenanceRange pr,
218 : location_{pr}, text_{t}, usageWarning_{warning} {}
219 Message(common::UsageWarning warning, ProvenanceRange pr,
221 : location_{pr}, text_{s}, usageWarning_{warning} {}
222 Message(common::UsageWarning warning, ProvenanceRange pr,
224 : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
227 : location_{csr}, text_{t} {}
229 : location_{csr}, text_{s} {}
231 : location_{csr}, text_{std::move(s)} {}
233 : location_{csr}, text_{t} {}
237 : location_{csr}, text_{t}, languageFeature_{feature} {}
238 Message(common::LanguageFeature feature,
CharBlock csr,
240 : location_{csr}, text_{s}, languageFeature_{feature} {}
243 : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
247 : location_{csr}, text_{t}, usageWarning_{warning} {}
248 Message(common::UsageWarning warning,
CharBlock csr,
250 : location_{csr}, text_{s}, usageWarning_{warning} {}
252 : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
254 template <
typename RANGE,
typename A,
typename... As>
257 t, std::forward<A>(x), std::forward<As>(xs)...}} {}
258 template <
typename RANGE,
typename A,
typename... As>
259 Message(common::LanguageFeature feature, RANGE r,
const MessageFixedText &t,
262 t, std::forward<A>(x), std::forward<As>(xs)...}},
263 languageFeature_{feature} {}
264 template <
typename RANGE,
typename A,
typename... As>
268 t, std::forward<A>(x), std::forward<As>(xs)...}},
269 usageWarning_{warning} {}
271 Reference attachment()
const {
return attachment_; }
273 void SetContext(Message *c) {
275 attachmentIsContext_ =
true;
277 Message &Attach(Message *);
278 Message &Attach(std::unique_ptr<Message> &&);
279 template <
typename... A> Message &Attach(A &&...args) {
280 return Attach(
new Message{std::forward<A>(args)...});
283 bool SortBefore(
const Message &that)
const;
284 bool IsFatal()
const;
285 Severity severity()
const;
286 Message &set_severity(Severity);
287 std::optional<common::LanguageFeature> languageFeature()
const;
288 Message &set_languageFeature(common::LanguageFeature);
289 std::optional<common::UsageWarning> usageWarning()
const;
290 Message &set_usageWarning(common::UsageWarning);
291 std::string ToString()
const;
292 std::optional<ProvenanceRange> GetProvenanceRange(
295 bool echoSourceLine =
true,
302 bool IsMergeable()
const {
303 return std::holds_alternative<MessageExpectedText>(text_);
305 bool Merge(
const Message &);
306 bool operator==(
const Message &that)
const;
307 bool operator!=(
const Message &that)
const {
return !(*
this == that); }
310 bool AtSameLocation(
const Message &)
const;
311 std::variant<ProvenanceRange, CharBlock> location_;
312 std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
314 bool attachmentIsContext_{
false};
315 Reference attachment_;
316 std::optional<common::LanguageFeature> languageFeature_;
317 std::optional<common::UsageWarning> usageWarning_;
323 Messages(Messages &&that) : messages_{std::move(that.messages_)} {}
324 Messages &operator=(Messages &&that) {
325 messages_ = std::move(that.messages_);
329 std::list<Message> &messages() {
return messages_; }
330 bool empty()
const {
return messages_.empty(); }
331 void clear() { messages_.clear(); }
333 template <
typename... A>
Message &Say(A &&...args) {
334 return messages_.emplace_back(std::forward<A>(args)...);
337 template <
typename... A>
338 Message *Warn(
bool isInModuleFile,
340 common::LanguageFeature feature, A &&...args) {
341 if (!isInModuleFile && control.ShouldWarn(feature)) {
342 return &AddWarning(feature, std::forward<A>(args)...);
347 template <
typename... A>
348 Message *Warn(
bool isInModuleFile,
350 common::UsageWarning warning, A &&...args) {
351 if (!isInModuleFile && control.ShouldWarn(warning)) {
352 return &AddWarning(warning, std::forward<A>(args)...);
357 void Annex(Messages &&that) {
358 messages_.splice(messages_.end(), that.messages_);
362 void Merge(Messages &&);
363 void Copy(
const Messages &);
366 bool echoSourceLines =
true,
368 std::size_t maxErrorsToEmit = 0,
bool warningsAreErrors =
false)
const;
369 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
370 bool AnyFatalError(
bool warningsAreErrors =
false)
const;
373 template <
typename... A>
374 Message &AddWarning(common::UsageWarning warning, A &&...args) {
375 return messages_.emplace_back(warning, std::forward<A>(args)...);
377 template <
typename... A>
378 Message &AddWarning(common::LanguageFeature feature, A &&...args) {
379 return messages_.emplace_back(feature, std::forward<A>(args)...);
381 std::list<Message> messages_;
384class ContextualMessages {
386 ContextualMessages() =
default;
388 explicit ContextualMessages(
Messages *m) : messages_{m} {}
389 ContextualMessages(
const ContextualMessages &that)
390 : at_{that.at_}, messages_{that.messages_} {}
393 Messages *messages()
const {
return messages_; }
394 Message::Reference contextMessage()
const {
return contextMessage_; }
395 bool empty()
const {
return !messages_ || messages_->empty(); }
402 return common::ScopedSet(at_, std::move(at));
407 m = contextMessage_.get();
409 return common::ScopedSet(contextMessage_, m);
415 return common::ScopedSet(messages_, &buffer);
419 return common::ScopedSet(messages_,
nullptr);
422 template <
typename... A>
Message *Say(A &&...args) {
423 return Say(at_, std::forward<A>(args)...);
427 if (messages_ !=
nullptr) {
428 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
429 if (contextMessage_) {
430 msg.SetContext(contextMessage_.get());
438 template <
typename... A>
439 Message *Say(std::optional<CharBlock> at, A &&...args) {
440 return Say(at.value_or(at_), std::forward<A>(args)...);
444 if (messages_ !=
nullptr) {
445 if (contextMessage_) {
446 msg.SetContext(contextMessage_.get());
448 return &messages_->Say(std::move(msg));
454 template <
typename FeatureOrUsageWarning,
typename... A>
455 Message *Warn(
bool isInModuleFile,
457 FeatureOrUsageWarning feature,
CharBlock at, A &&...args) {
458 if (messages_ !=
nullptr) {
460 msg{messages_->Warn(isInModuleFile, control, feature, at,
461 std::forward<A>(args)...)}) {
462 if (contextMessage_) {
463 msg->SetContext(contextMessage_.get());
471 template <
typename FeatureOrUsageWarning,
typename... A>
472 Message *Warn(
bool isInModuleFile,
474 FeatureOrUsageWarning feature, A &&...args) {
476 isInModuleFile, control, feature, at_, std::forward<A>(args)...);
479 template <
typename FeatureOrUsageWarning,
typename... A>
480 Message *Warn(
bool isInModuleFile,
482 FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
483 return Warn(isInModuleFile, control, feature, at.value_or(at_),
484 std::forward<A>(args)...);
490 Message::Reference contextMessage_;