From 4dd84b651292a64a96cc0ba24fb5c0cba9ecee0d Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 30 Jan 2018 11:53:49 -0800 Subject: [PATCH] [flang] Add message.{h,cc}. Original-commit: flang-compiler/f18@9c21346414a4e13f1bef8b40607880fbcb9bb7f6 --- flang/message.cc | 24 +++++++++++++ flang/message.h | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 flang/message.cc create mode 100644 flang/message.h diff --git a/flang/message.cc b/flang/message.cc new file mode 100644 index 0000000..55cdbf4 --- /dev/null +++ b/flang/message.cc @@ -0,0 +1,24 @@ +#include "message.h" + +namespace Fortran { + +std::ostream &operator<<(std::ostream &o, const Message &msg) { + if (msg.context()) { + o << *msg.context(); + } + o << "at line " << msg.position().lineNumber(); + int column = msg.position().column(); + if (column > 0) { + o << "(column " << column << ")"; + } + o << ": " << msg.message() << '\n'; + return o; +} + +std::ostream &operator<<(std::ostream &o, const Messages &ms) { + for (const auto &msg : ms) { + o << msg; + } + return o; +} +} // namespace Fortran diff --git a/flang/message.h b/flang/message.h new file mode 100644 index 0000000..c98ea9b --- /dev/null +++ b/flang/message.h @@ -0,0 +1,106 @@ +#ifndef FORTRAN_MESSAGE_H_ +#define FORTRAN_MESSAGE_H_ + +// Defines a representation for sequences of compiler messages. +// Supports nested contextualization. + +#include "idioms.h" +#include "position.h" +#include +#include +#include +#include +#include + +namespace Fortran { + +class Message; +using MessageContext = std::shared_ptr; + +class Message { + public: + Message(Position pos, const std::string &msg, MessageContext ctx = nullptr) + : position_{pos}, message_{msg}, context_{ctx} {} + Message(Position pos, std::string &&msg, MessageContext ctx = nullptr) + : position_{pos}, message_{std::move(msg)}, context_{ctx} {} + Message(Position pos, const char *msg, MessageContext ctx = nullptr) + : position_{pos}, message_{msg}, context_{ctx} {} + Message(Position pos, char ch, MessageContext ctx = nullptr) + : position_{pos}, message_{"expected '"s + ch + '\''}, + context_{ctx} {} + + Message() {} + Message(const Message &) = default; + Message(Message &&) = default; + Message &operator=(const Message &that) = default; + Message &operator=(Message &&that) = default; + + Position position() const { return position_; } + std::string message() const { return message_; } + MessageContext context() const { return context_; } + + bool operator<(const Message &that) const { + return position_ < that.position_; + } + + private: + Position position_; + std::string message_; + MessageContext context_; +}; + +class Messages { + using list_type = std::forward_list; + public: + using iterator = list_type::iterator; + using const_iterator = list_type::const_iterator; + + Messages() {} + Messages(Messages &&that) + : messages_{std::move(that.messages_)}, last_{that.last_} {} + Messages &operator=(Messages &&that) { + swap(that); + return *this; + } + + void swap(Messages &that) { + messages_.swap(that.messages_); + std::swap(last_, that.last_); + } + + iterator begin() { return messages_.begin(); } + iterator end() { return messages_.end(); } + const_iterator begin() const { return messages_.cbegin(); } + const_iterator end() const { return messages_.cend(); } + const_iterator cbegin() const { return messages_.cbegin(); } + const_iterator cend() const { return messages_.cend(); } + + void Add(Message &&m) { + if (messages_.empty()) { + messages_.emplace_front(std::move(m)); + last_ = messages_.begin(); + } else { + last_ = messages_.emplace_after(last_, std::move(m)); + } + } + + void Annex(Messages *that) { + if (!that->messages_.empty()) { + if (messages_.empty()) { + messages_ = std::move(that->messages_); + } else { + messages_.splice_after(last_, that->messages_); + } + last_ = that->last_; + } + } + + private: + list_type messages_; + iterator last_; // valid iff messages_ nonempty +}; + +std::ostream &operator<<(std::ostream &, const Message &); +std::ostream &operator<<(std::ostream &, const Messages &); +} // namespace Fortran +#endif // FORTRAN_MESSAGE_H_ -- 2.7.4