9#ifndef FORTRAN_PARSER_MESSAGE_H_
10#define FORTRAN_PARSER_MESSAGE_H_
15#include "char-block.h"
17#include "provenance.h"
18#include "flang/Common/Fortran-features.h"
19#include "flang/Common/idioms.h"
20#include "flang/Common/reference-counted.h"
21#include "flang/Common/restorer.h"
24#include <forward_list>
50 const char str[], std::size_t n, Severity severity = Severity::None)
51 : text_{str, n}, severity_{severity} {}
58 bool empty()
const {
return text_.empty(); }
59 Severity severity()
const {
return severity_; }
64 bool IsFatal()
const {
65 return severity_ == Severity::Error || severity_ == Severity::Todo;
70 Severity severity_{Severity::None};
73inline namespace literals {
75 const char str[], std::size_t n) {
78constexpr MessageFixedText
operator""_warn_en_US(
79 const char str[], std::size_t n) {
80 return MessageFixedText{str, n, Severity::Warning};
82constexpr MessageFixedText
operator""_port_en_US(
83 const char str[], std::size_t n) {
84 return MessageFixedText{str, n, Severity::Portability};
86constexpr MessageFixedText
operator""_because_en_US(
87 const char str[], std::size_t n) {
88 return MessageFixedText{str, n, Severity::Because};
90constexpr MessageFixedText
operator""_todo_en_US(
91 const char str[], std::size_t n) {
92 return MessageFixedText{str, n, Severity::Todo};
94constexpr MessageFixedText
operator""_en_US(
const char str[], std::size_t n) {
95 return MessageFixedText{str, n, Severity::None};
106 template <
typename... A>
108 : severity_{text.severity()} {
109 Format(&text, Convert(std::forward<A>(x))...);
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_; }
121 severity_ = severity;
124 std::string MoveString() {
return std::move(string_); }
126 return severity_ == that.severity_ && string_ == that.string_;
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_;
163 if (n == std::string::npos) {
181 std::string ToString()
const;
185 std::variant<CharBlock, SetOfChars> u_;
198 : location_{pr}, text_{t} {}
200 : location_{pr}, text_{s} {}
202 : location_{pr}, text_{std::move(s)} {}
204 : location_{pr}, text_{t} {}
208 : location_{pr}, text_{t}, languageFeature_{feature} {}
211 : location_{pr}, text_{s}, languageFeature_{feature} {}
214 : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
218 : location_{pr}, text_{t}, usageWarning_{warning} {}
221 : location_{pr}, text_{s}, usageWarning_{warning} {}
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} {}
240 : location_{csr}, text_{s}, languageFeature_{feature} {}
243 : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
247 : location_{csr}, text_{t}, usageWarning_{warning} {}
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>
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_; }
275 attachmentIsContext_ =
true;
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)
const;
301 bool IsMergeable()
const {
302 return std::holds_alternative<MessageExpectedText>(text_);
305 bool operator==(
const Message &that)
const;
306 bool operator!=(
const Message &that)
const {
return !(*
this == that); }
309 bool AtSameLocation(
const Message &)
const;
310 std::variant<ProvenanceRange, CharBlock> location_;
311 std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
313 bool attachmentIsContext_{
false};
315 std::optional<common::LanguageFeature> languageFeature_;
316 std::optional<common::UsageWarning> usageWarning_;
324 messages_ = std::move(that.messages_);
328 std::list<Message> &messages() {
return messages_; }
329 bool empty()
const {
return messages_.empty(); }
330 void clear() { messages_.clear(); }
332 template <
typename... A>
Message &Say(A &&...args) {
333 return messages_.emplace_back(std::forward<A>(args)...);
336 template <
typename... A>
337 Message &Say(common::LanguageFeature feature, A &&...args) {
338 return Say(std::forward<A>(args)...).set_languageFeature(feature);
341 template <
typename... A>
342 Message &Say(common::UsageWarning warning, A &&...args) {
343 return Say(std::forward<A>(args)...).set_usageWarning(warning);
347 messages_.splice(messages_.end(), that.messages_);
355 bool echoSourceLines =
true)
const;
356 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
357 bool AnyFatalError()
const;
360 std::list<Message> messages_;
369 : at_{that.at_}, messages_{that.messages_} {}
372 Messages *messages()
const {
return messages_; }
374 bool empty()
const {
return !messages_ || messages_->empty(); }
381 return common::ScopedSet(at_, std::move(at));
386 m = contextMessage_.get();
388 return common::ScopedSet(contextMessage_, m);
394 return common::ScopedSet(messages_, &buffer);
398 return common::ScopedSet(messages_,
nullptr);
401 template <
typename... A>
Message *Say(A &&...args) {
402 return Say(at_, std::forward<A>(args)...);
406 if (messages_ !=
nullptr) {
407 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
408 if (contextMessage_) {
409 msg.SetContext(contextMessage_.get());
417 template <
typename... A>
418 Message *Say(std::optional<CharBlock> at, A &&...args) {
419 return Say(at.value_or(at_), std::forward<A>(args)...);
422 template <
typename... A>
423 Message *Say(common::LanguageFeature feature, A &&...args) {
424 Message *msg{Say(std::forward<A>(args)...)};
426 msg->set_languageFeature(feature);
431 template <
typename... A>
432 Message *Say(common::UsageWarning warning, A &&...args) {
433 Message *msg{Say(std::forward<A>(args)...)};
435 msg->set_usageWarning(warning);
441 if (messages_ !=
nullptr) {
442 if (contextMessage_) {
443 msg.SetContext(contextMessage_.get());
445 return &messages_->Say(std::move(msg));
Definition: reference-counted.h:19
Definition: restorer.h:24
Definition: provenance.h:281
Definition: char-block.h:28
Definition: message.h:363
Definition: message.h:160
Definition: message.h:104
Definition: message.h:188
Definition: message.h:319
Definition: check-expression.h:19
Definition: char-set.h:23