119class MessageFormattedText {
121 template <
typename... A>
123 : severity_{text.severity()} {
124 Format(&text, Convert(std::forward<A>(x))...);
126 MessageFormattedText(
const MessageFormattedText &) =
default;
127 MessageFormattedText(MessageFormattedText &&) =
default;
128 MessageFormattedText &operator=(
const MessageFormattedText &) =
default;
129 MessageFormattedText &operator=(MessageFormattedText &&) =
default;
130 const std::string &string()
const {
return string_; }
131 bool IsFatal()
const {
return IsFatalSeverity(severity_); }
132 Severity severity()
const {
return severity_; }
133 MessageFormattedText &set_severity(Severity severity) {
134 severity_ = severity;
137 std::string MoveString() {
return std::move(string_); }
138 bool operator==(
const MessageFormattedText &that)
const {
139 return severity_ == that.severity_ && string_ == that.string_;
141 bool operator!=(
const MessageFormattedText &that)
const {
142 return !(*
this == that);
148 template <
typename A> A Convert(
const A &x) {
149 static_assert(!std::is_class_v<std::decay_t<A>>);
152 template <
typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
153 static_assert(!std::is_class_v<std::decay_t<A>>);
156 const char *Convert(
const char *s) {
return s; }
157 const char *Convert(
char *s) {
return s; }
158 const char *Convert(
const std::string &);
159 const char *Convert(std::string &&);
160 const char *Convert(
const std::string_view &);
161 const char *Convert(std::string_view &&);
163 const char *Convert(llvm::StringRef);
164 std::intmax_t Convert(std::int64_t x) {
return x; }
165 std::uintmax_t Convert(std::uint64_t x) {
return x; }
169 std::forward_list<std::string> conversions_;
206 Message(
const Message &) =
default;
207 Message(Message &&) =
default;
208 Message &operator=(
const Message &) =
default;
209 Message &operator=(Message &&) =
default;
212 : location_{pr}, text_{t} {}
214 : location_{pr}, text_{s} {}
216 : location_{pr}, text_{std::move(s)} {}
218 : location_{pr}, text_{t} {}
220 Message(common::LanguageFeature feature, ProvenanceRange pr,
222 : location_{pr}, text_{t}, languageFeature_{feature} {}
223 Message(common::LanguageFeature feature, ProvenanceRange pr,
225 : location_{pr}, text_{s}, languageFeature_{feature} {}
226 Message(common::LanguageFeature feature, ProvenanceRange pr,
228 : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
230 Message(common::UsageWarning warning, ProvenanceRange pr,
232 : location_{pr}, text_{t}, usageWarning_{warning} {}
233 Message(common::UsageWarning warning, ProvenanceRange pr,
235 : location_{pr}, text_{s}, usageWarning_{warning} {}
236 Message(common::UsageWarning warning, ProvenanceRange pr,
238 : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
241 : location_{csr}, text_{t} {}
243 : location_{csr}, text_{s} {}
245 : location_{csr}, text_{std::move(s)} {}
247 : location_{csr}, text_{t} {}
251 : location_{csr}, text_{t}, languageFeature_{feature} {}
252 Message(common::LanguageFeature feature,
CharBlock csr,
254 : location_{csr}, text_{s}, languageFeature_{feature} {}
257 : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
261 : location_{csr}, text_{t}, usageWarning_{warning} {}
262 Message(common::UsageWarning warning,
CharBlock csr,
264 : location_{csr}, text_{s}, usageWarning_{warning} {}
266 : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
268 template <
typename RANGE,
typename A,
typename... As>
271 t, std::forward<A>(x), std::forward<As>(xs)...}} {}
272 template <
typename RANGE,
typename A,
typename... As>
273 Message(common::LanguageFeature feature, RANGE r,
const MessageFixedText &t,
276 t, std::forward<A>(x), std::forward<As>(xs)...}},
277 languageFeature_{feature} {}
278 template <
typename RANGE,
typename A,
typename... As>
282 t, std::forward<A>(x), std::forward<As>(xs)...}},
283 usageWarning_{warning} {}
285 Reference attachment()
const {
return attachment_; }
287 void SetContext(Message *c) {
289 attachmentIsContext_ =
true;
291 Message &Attach(Message *);
292 Message &Attach(std::unique_ptr<Message> &&);
293 template <
typename... A> Message &Attach(A &&...args) {
294 return Attach(
new Message{std::forward<A>(args)...});
297 bool SortBefore(
const Message &that)
const;
298 bool IsFatal()
const;
299 Severity severity()
const;
300 Message &set_severity(Severity);
301 std::optional<common::LanguageFeature> languageFeature()
const;
302 Message &set_languageFeature(common::LanguageFeature);
303 std::optional<common::UsageWarning> usageWarning()
const;
304 Message &set_usageWarning(common::UsageWarning);
305 std::string ToString()
const;
306 std::optional<ProvenanceRange> GetProvenanceRange(
309 bool echoSourceLine =
true,
316 bool IsMergeable()
const {
317 return std::holds_alternative<MessageExpectedText>(text_);
319 bool Merge(
const Message &);
320 bool operator==(
const Message &that)
const;
321 bool operator!=(
const Message &that)
const {
return !(*
this == that); }
322 bool AtSameLocation(
const Message &)
const;
325 std::variant<ProvenanceRange, CharBlock> location_;
326 std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
328 bool attachmentIsContext_{
false};
329 Reference attachment_;
330 std::optional<common::LanguageFeature> languageFeature_;
331 std::optional<common::UsageWarning> usageWarning_;
337 Messages(Messages &&that) : messages_{std::move(that.messages_)} {}
338 Messages &operator=(Messages &&that) {
339 messages_ = std::move(that.messages_);
343 std::list<Message> &messages() {
return messages_; }
344 const std::list<Message> &messages()
const {
return messages_; }
345 bool empty()
const {
return messages_.empty(); }
346 void clear() { messages_.clear(); }
348 template <
typename... A>
Message &Say(A &&...args) {
349 return messages_.emplace_back(std::forward<A>(args)...);
352 template <
typename... A>
353 Message *Warn(
bool isInModuleFile,
355 common::LanguageFeature feature, A &&...args) {
356 if (!isInModuleFile && control.ShouldWarn(feature)) {
357 return &AddWarning(feature, std::forward<A>(args)...);
362 template <
typename... A>
363 Message *Warn(
bool isInModuleFile,
365 common::UsageWarning warning, A &&...args) {
366 if (!isInModuleFile && control.ShouldWarn(warning)) {
367 return &AddWarning(warning, std::forward<A>(args)...);
372 void Annex(Messages &&that) {
373 messages_.splice(messages_.end(), that.messages_);
377 void Merge(Messages &&);
378 void Copy(
const Messages &);
381 bool echoSourceLines =
true,
383 std::size_t maxErrorsToEmit = 0,
bool warningsAreErrors =
false)
const;
384 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
385 bool AnyFatalError(
bool warningsAreErrors =
false)
const;
388 template <
typename... A>
389 Message &AddWarning(common::UsageWarning warning, A &&...args) {
390 return messages_.emplace_back(warning, std::forward<A>(args)...);
392 template <
typename... A>
393 Message &AddWarning(common::LanguageFeature feature, A &&...args) {
394 return messages_.emplace_back(feature, std::forward<A>(args)...);
396 std::list<Message> messages_;
399class ContextualMessages {
401 ContextualMessages() =
default;
403 explicit ContextualMessages(
Messages *m) : messages_{m} {}
404 ContextualMessages(
const ContextualMessages &that)
405 : at_{that.at_}, messages_{that.messages_} {}
408 Messages *messages()
const {
return messages_; }
409 Message::Reference contextMessage()
const {
return contextMessage_; }
410 bool empty()
const {
return !messages_ || messages_->empty(); }
417 return common::ScopedSet(at_, std::move(at));
422 m = contextMessage_.get();
424 return common::ScopedSet(contextMessage_, m);
430 return common::ScopedSet(messages_, &buffer);
434 return common::ScopedSet(messages_,
nullptr);
437 template <
typename... A>
Message *Say(A &&...args) {
438 return Say(at_, std::forward<A>(args)...);
442 if (messages_ !=
nullptr) {
443 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
444 if (contextMessage_) {
445 msg.SetContext(contextMessage_.get());
453 template <
typename... A>
454 Message *Say(std::optional<CharBlock> at, A &&...args) {
455 return Say(at.value_or(at_), std::forward<A>(args)...);
459 if (messages_ !=
nullptr) {
460 if (contextMessage_) {
461 msg.SetContext(contextMessage_.get());
463 return &messages_->Say(std::move(msg));
469 template <
typename FeatureOrUsageWarning,
typename... A>
470 Message *Warn(
bool isInModuleFile,
472 FeatureOrUsageWarning feature,
CharBlock at, A &&...args) {
473 if (messages_ !=
nullptr) {
475 msg{messages_->Warn(isInModuleFile, control, feature, at,
476 std::forward<A>(args)...)}) {
477 if (contextMessage_) {
478 msg->SetContext(contextMessage_.get());
486 template <
typename FeatureOrUsageWarning,
typename... A>
487 Message *Warn(
bool isInModuleFile,
489 FeatureOrUsageWarning feature, A &&...args) {
491 isInModuleFile, control, feature, at_, std::forward<A>(args)...);
494 template <
typename FeatureOrUsageWarning,
typename... A>
495 Message *Warn(
bool isInModuleFile,
497 FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
498 return Warn(isInModuleFile, control, feature, at.value_or(at_),
499 std::forward<A>(args)...);
505 Message::Reference contextMessage_;