[flang-commits] [flang] 2895771 - [flang] Add nonfatal message classes
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Tue Mar 8 11:40:53 PST 2022
Author: Peter Klausler
Date: 2022-03-08T11:40:45-08:00
New Revision: 2895771faf4f8e63fabeb6f35fd5b70b925b0234
URL: https://github.com/llvm/llvm-project/commit/2895771faf4f8e63fabeb6f35fd5b70b925b0234
DIFF: https://github.com/llvm/llvm-project/commit/2895771faf4f8e63fabeb6f35fd5b70b925b0234.diff
LOG: [flang] Add nonfatal message classes
F18 presently has fatal and non-fatal diagnostic messages. We'd like
to make non-fatal warnings stand out better in the output of the compiler.
This will turn out to be a large change that affects many files.
This patch is just the first part. It converts a Boolean isFatal_ data
member of the message classes into a severity code, and defines four
of these codes (Error, Warning, Portability, and a catch-all Other).
Later patches will result from sweeping over the parser and semantics,
changing most non-fatal diagnostic messages into warnings and portability
notes.
Differential Revision: https://reviews.llvm.org/D121228
Added:
Modified:
flang/docs/Parsing.md
flang/include/flang/Parser/message.h
flang/lib/Parser/message.cpp
flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/resolve-names-utils.cpp
flang/lib/Semantics/resolve-names-utils.h
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/docs/Parsing.md b/flang/docs/Parsing.md
index dec63e6fbdab4..172a13946601e 100644
--- a/flang/docs/Parsing.md
+++ b/flang/docs/Parsing.md
@@ -133,10 +133,20 @@ indicators within the parser and in the parse tree.
Message texts, and snprintf-like formatting strings for constructing
messages, are instantiated in the various components of the parser with
-C++ user defined character literals tagged with `_err_en_US` and `_en_US`
-(signifying fatality and language, with the default being the dialect of
-English used in the United States) so that they may be easily identified
-for localization. As described above, messages are associated with
+C++ user defined character literals tagged with `_err_en_US`, `_warn_en_US`,
+`port_en_US`, and `_en_US` to signify severity and language; the default
+language is the dialect of English used in the United States.
+
+All "fatal" errors that do not immediately abort compilation but do
+prevent the generation of binary and module files are `_err_en_US`.
+Warnings about detected flaws in the program that probably indicate
+problems worth attention are `_warn_en_US`.
+Non-conforming extensions, legacy features, and obsolescent or deleted
+features will raise `_port_en_US` messages when those are enabled.
+Other messages have a simple `_en_US` suffix, including all messages
+that are explanatory attachments.
+
+As described above, messages are associated with
source code positions by means of provenance values.
## The Parse Tree
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 50ab3118543f5..432ee36862d4c 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -29,34 +29,45 @@
namespace Fortran::parser {
-// Use "..."_err_en_US and "..."_en_US literals to define the static
-// text and fatality of a message.
+// Use "..."_err_en_US, "..."_warn_en_US, and "..."_en_US literals to define
+// the static text and fatality of a message.
+enum class Severity { Error, Warning, Portability, None };
+
class MessageFixedText {
public:
+ constexpr MessageFixedText() {}
constexpr MessageFixedText(
- const char str[], std::size_t n, bool isFatal = false)
- : text_{str, n}, isFatal_{isFatal} {}
+ const char str[], std::size_t n, Severity severity = Severity::None)
+ : text_{str, n}, severity_{severity} {}
constexpr MessageFixedText(const MessageFixedText &) = default;
constexpr MessageFixedText(MessageFixedText &&) = default;
constexpr MessageFixedText &operator=(const MessageFixedText &) = default;
constexpr MessageFixedText &operator=(MessageFixedText &&) = default;
CharBlock text() const { return text_; }
- bool isFatal() const { return isFatal_; }
+ Severity severity() const { return severity_; }
+ bool isFatal() const { return severity_ == Severity::Error; }
private:
CharBlock text_;
- bool isFatal_{false};
+ Severity severity_{Severity::None};
};
inline namespace literals {
-constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) {
- return MessageFixedText{str, n, false /* not fatal */};
-}
-
constexpr MessageFixedText operator""_err_en_US(
const char str[], std::size_t n) {
- return MessageFixedText{str, n, true /* fatal */};
+ return MessageFixedText{str, n, Severity::Error};
+}
+constexpr MessageFixedText operator""_warn_en_US(
+ const char str[], std::size_t n) {
+ return MessageFixedText{str, n, Severity::Warning};
+}
+constexpr MessageFixedText operator""_port_en_US(
+ const char str[], std::size_t n) {
+ return MessageFixedText{str, n, Severity::Portability};
+}
+constexpr MessageFixedText operator""_en_US(const char str[], std::size_t n) {
+ return MessageFixedText{str, n, Severity::None};
}
} // namespace literals
@@ -69,7 +80,7 @@ class MessageFormattedText {
public:
template <typename... A>
MessageFormattedText(const MessageFixedText &text, A &&...x)
- : isFatal_{text.isFatal()} {
+ : severity_{text.severity()} {
Format(&text, Convert(std::forward<A>(x))...);
}
MessageFormattedText(const MessageFormattedText &) = default;
@@ -77,7 +88,8 @@ class MessageFormattedText {
MessageFormattedText &operator=(const MessageFormattedText &) = default;
MessageFormattedText &operator=(MessageFormattedText &&) = default;
const std::string &string() const { return string_; }
- bool isFatal() const { return isFatal_; }
+ bool isFatal() const { return severity_ == Severity::Error; }
+ Severity severity() const { return severity_; }
std::string MoveString() { return std::move(string_); }
private:
@@ -104,7 +116,7 @@ class MessageFormattedText {
std::intmax_t Convert(std::int64_t x) { return x; }
std::uintmax_t Convert(std::uint64_t x) { return x; }
- bool isFatal_{false};
+ Severity severity_;
std::string string_;
std::forward_list<std::string> conversions_; // preserves created strings
};
@@ -186,6 +198,7 @@ class Message : public common::ReferenceCounted<Message> {
bool SortBefore(const Message &that) const;
bool IsFatal() const;
+ Severity severity() const;
std::string ToString() const;
std::optional<ProvenanceRange> GetProvenanceRange(
const AllCookedSources &) const;
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index fd4a52c895bf9..63515fd2e0fa5 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -155,12 +155,14 @@ bool Message::SortBefore(const Message &that) const {
location_, that.location_);
}
-bool Message::IsFatal() const {
+bool Message::IsFatal() const { return severity() == Severity::Error; }
+
+Severity Message::severity() const {
return std::visit(
common::visitors{
- [](const MessageExpectedText &) { return true; },
- [](const MessageFixedText &x) { return x.isFatal(); },
- [](const MessageFormattedText &x) { return x.isFatal(); },
+ [](const MessageExpectedText &) { return Severity::Error; },
+ [](const MessageFixedText &x) { return x.severity(); },
+ [](const MessageFormattedText &x) { return x.severity(); },
},
text_);
}
@@ -203,8 +205,18 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLine) const {
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
std::string text;
- if (IsFatal()) {
- text += "error: ";
+ switch (severity()) {
+ case Severity::Error:
+ text = "error: ";
+ break;
+ case Severity::Warning:
+ text = "warning: ";
+ break;
+ case Severity::Portability:
+ text = "portability: ";
+ break;
+ case Severity::None:
+ break;
}
text += ToString();
const AllSources &sources{allCooked.allSources()};
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 15e8b79052242..da266c15f8e4c 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -38,7 +38,8 @@ bool FormatErrorReporter::Say(const common::FormatMessage &msg) {
return false;
}
parser::MessageFormattedText text{
- parser::MessageFixedText(msg.text, strlen(msg.text), msg.isError),
+ parser::MessageFixedText{msg.text, strlen(msg.text),
+ msg.isError ? parser::Severity::Error : parser::Severity::Warning},
msg.arg};
if (formatCharBlock_.size()) {
// The input format is a folded expression. Error markers span the full
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 95118202e9fe3..ce1c37ef59a40 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -946,7 +946,8 @@ Scope *ModFileReader::Read(const SourceName &name,
for (auto &msg : parsing.messages().messages()) {
std::string str{msg.ToString()};
Say(name, ancestorName,
- parser::MessageFixedText{str.c_str(), str.size()}, path);
+ parser::MessageFixedText{str.c_str(), str.size(), msg.severity()},
+ path);
}
}
return nullptr;
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index da33359e29614..4c3c32e1a0af6 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -44,10 +44,10 @@ Symbol &Resolve(const parser::Name &name, Symbol &symbol) {
return *Resolve(name, &symbol);
}
-parser::MessageFixedText WithIsFatal(
- const parser::MessageFixedText &msg, bool isFatal) {
+parser::MessageFixedText WithSeverity(
+ const parser::MessageFixedText &msg, parser::Severity severity) {
return parser::MessageFixedText{
- msg.text().begin(), msg.text().size(), isFatal};
+ msg.text().begin(), msg.text().size(), severity};
}
bool IsIntrinsicOperator(
@@ -576,7 +576,7 @@ bool EquivalenceSets::CheckObject(const parser::Name &name) {
return false; // an error has already occurred
}
currObject_.symbol = name.symbol;
- parser::MessageFixedText msg{"", 0};
+ parser::MessageFixedText msg;
const Symbol &symbol{*name.symbol};
if (symbol.owner().IsDerivedType()) { // C8107
msg = "Derived type component '%s'"
diff --git a/flang/lib/Semantics/resolve-names-utils.h b/flang/lib/Semantics/resolve-names-utils.h
index 032aa1943cb61..d0986fdfc139e 100644
--- a/flang/lib/Semantics/resolve-names-utils.h
+++ b/flang/lib/Semantics/resolve-names-utils.h
@@ -44,9 +44,9 @@ class SemanticsContext;
Symbol &Resolve(const parser::Name &, Symbol &);
Symbol *Resolve(const parser::Name &, Symbol *);
-// Create a copy of msg with a new isFatal value.
-parser::MessageFixedText WithIsFatal(
- const parser::MessageFixedText &msg, bool isFatal);
+// Create a copy of msg with a new severity.
+parser::MessageFixedText WithSeverity(
+ const parser::MessageFixedText &msg, parser::Severity);
bool IsIntrinsicOperator(const SemanticsContext &, const SourceName &);
bool IsLogicalConstant(const SemanticsContext &, const SourceName &);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4da150599c88a..07135b5796d46 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6654,9 +6654,9 @@ Symbol &ModuleVisitor::SetAccess(
// PUBLIC/PRIVATE already set: make it a fatal error if it changed
Attr prev = attrs.test(Attr::PUBLIC) ? Attr::PUBLIC : Attr::PRIVATE;
Say(name,
- WithIsFatal(
+ WithSeverity(
"The accessibility of '%s' has already been specified as %s"_en_US,
- attr != prev),
+ attr != prev ? parser::Severity::Error : parser::Severity::Warning),
MakeOpName(name), EnumToString(prev));
} else {
attrs.set(attr);
More information about the flang-commits
mailing list