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 const std::list<Message> &messages()
const {
return messages_; }
343 bool empty()
const {
return messages_.empty(); }
344 void clear() { messages_.clear(); }
346 template <
typename... A>
Message &Say(A &&...args) {
347 return messages_.emplace_back(std::forward<A>(args)...);
350 template <
typename... A>
351 Message *Warn(
bool isInModuleFile,
353 common::LanguageFeature feature, A &&...args) {
354 if (!isInModuleFile && control.ShouldWarn(feature)) {
355 return &AddWarning(feature, std::forward<A>(args)...);
360 template <
typename... A>
361 Message *Warn(
bool isInModuleFile,
363 common::UsageWarning warning, A &&...args) {
364 if (!isInModuleFile && control.ShouldWarn(warning)) {
365 return &AddWarning(warning, std::forward<A>(args)...);
370 void Annex(Messages &&that) {
371 messages_.splice(messages_.end(), that.messages_);
375 void Merge(Messages &&);
376 void Copy(
const Messages &);
379 bool echoSourceLines =
true,
381 std::size_t maxErrorsToEmit = 0,
bool warningsAreErrors =
false)
const;
382 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
383 bool AnyFatalError(
bool warningsAreErrors =
false)
const;
386 template <
typename... A>
387 Message &AddWarning(common::UsageWarning warning, A &&...args) {
388 return messages_.emplace_back(warning, std::forward<A>(args)...);
390 template <
typename... A>
391 Message &AddWarning(common::LanguageFeature feature, A &&...args) {
392 return messages_.emplace_back(feature, std::forward<A>(args)...);
394 std::list<Message> messages_;
397class ContextualMessages {
399 ContextualMessages() =
default;
401 explicit ContextualMessages(
Messages *m) : messages_{m} {}
402 ContextualMessages(
const ContextualMessages &that)
403 : at_{that.at_}, messages_{that.messages_} {}
406 Messages *messages()
const {
return messages_; }
407 Message::Reference contextMessage()
const {
return contextMessage_; }
408 bool empty()
const {
return !messages_ || messages_->empty(); }
415 return common::ScopedSet(at_, std::move(at));
420 m = contextMessage_.get();
422 return common::ScopedSet(contextMessage_, m);
428 return common::ScopedSet(messages_, &buffer);
432 return common::ScopedSet(messages_,
nullptr);
435 template <
typename... A>
Message *Say(A &&...args) {
436 return Say(at_, std::forward<A>(args)...);
440 if (messages_ !=
nullptr) {
441 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
442 if (contextMessage_) {
443 msg.SetContext(contextMessage_.get());
451 template <
typename... A>
452 Message *Say(std::optional<CharBlock> at, A &&...args) {
453 return Say(at.value_or(at_), std::forward<A>(args)...);
457 if (messages_ !=
nullptr) {
458 if (contextMessage_) {
459 msg.SetContext(contextMessage_.get());
461 return &messages_->Say(std::move(msg));
467 template <
typename FeatureOrUsageWarning,
typename... A>
468 Message *Warn(
bool isInModuleFile,
470 FeatureOrUsageWarning feature,
CharBlock at, A &&...args) {
471 if (messages_ !=
nullptr) {
473 msg{messages_->Warn(isInModuleFile, control, feature, at,
474 std::forward<A>(args)...)}) {
475 if (contextMessage_) {
476 msg->SetContext(contextMessage_.get());
484 template <
typename FeatureOrUsageWarning,
typename... A>
485 Message *Warn(
bool isInModuleFile,
487 FeatureOrUsageWarning feature, A &&...args) {
489 isInModuleFile, control, feature, at_, std::forward<A>(args)...);
492 template <
typename FeatureOrUsageWarning,
typename... A>
493 Message *Warn(
bool isInModuleFile,
495 FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
496 return Warn(isInModuleFile, control, feature, at.value_or(at_),
497 std::forward<A>(args)...);
503 Message::Reference contextMessage_;