Skip to content

Commit

Permalink
Added support of info messages (p4lang#4184)
Browse files Browse the repository at this point in the history
* Added support of info messages

* Fixed code style
  • Loading branch information
dmatousek authored Oct 11, 2023
1 parent 9c921cf commit d79e2e8
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 9 deletions.
15 changes: 12 additions & 3 deletions frontends/common/parser_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,28 @@ ParserOptions::ParserOptions() : Util::Options(defaultMessage) {
"Disable a compiler diagnostic, or disable all warnings if no "
"diagnostic is specified.",
OptionFlags::OptionalArgument);
registerOption(
"--Winfo", "diagnostic",
[](const char *diagnostic) {
if (diagnostic) {
P4CContext::get().setDiagnosticAction(diagnostic, DiagnosticAction::Info);
}
return true;
},
"Report an info message for a compiler diagnostic.", OptionFlags::OptionalArgument);
registerOption(
"--Wwarn", "diagnostic",
[](const char *diagnostic) {
if (diagnostic) {
P4CContext::get().setDiagnosticAction(diagnostic, DiagnosticAction::Warn);
} else {
auto action = DiagnosticAction::Warn;
P4CContext::get().setDefaultWarningDiagnosticAction(action);
P4CContext::get().setDefaultInfoDiagnosticAction(action);
}
return true;
},
"Report a warning for a compiler diagnostic, or treat all warnings "
"as warnings (the default) if no diagnostic is specified.",
"Report a warning for a compiler diagnostic, or treat all info messages as "
"warnings if no diagnostic is specified.",
OptionFlags::OptionalArgument);
registerOption(
"--Werror", "diagnostic",
Expand Down
10 changes: 10 additions & 0 deletions frontends/common/parser_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ class P4CContext : public BaseCompileContext {
/// @return the compiler options for this compilation context.
virtual ParserOptions &options() = 0;

/// @return the default diagnostic action for calls to `::info()`.
DiagnosticAction getDefaultInfoDiagnosticAction() final {
return errorReporter().getDefaultInfoDiagnosticAction();
}

/// set the default diagnostic action for calls to `::info()`.
void setDefaultInfoDiagnosticAction(DiagnosticAction action) {
errorReporter().setDefaultInfoDiagnosticAction(action);
}

/// @return the default diagnostic action for calls to `::warning()`.
DiagnosticAction getDefaultWarningDiagnosticAction() final {
return errorReporter().getDefaultWarningDiagnosticAction();
Expand Down
4 changes: 4 additions & 0 deletions lib/compile_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ BaseCompileContext::BaseCompileContext(const BaseCompileContext &other)

ErrorReporter &BaseCompileContext::errorReporter() { return errorReporterInstance; }

DiagnosticAction BaseCompileContext::getDefaultInfoDiagnosticAction() {
return DiagnosticAction::Info;
}

DiagnosticAction BaseCompileContext::getDefaultWarningDiagnosticAction() {
return DiagnosticAction::Warn;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/compile_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ class BaseCompileContext : public ICompileContext {
/// @return the error reporter for this compilation context.
virtual ErrorReporter &errorReporter();

/// @return the default diagnostic action for calls to `::info()`.
virtual DiagnosticAction getDefaultInfoDiagnosticAction();

/// @return the default diagnostic action for calls to `::warning()`.
virtual DiagnosticAction getDefaultWarningDiagnosticAction();

Expand Down
27 changes: 27 additions & 0 deletions lib/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,33 @@ void warning(const int kind, const char *format, Args... args) {
context.errorReporter().diagnose(action, kind, format, "", std::forward<Args>(args)...);
}

/// Report info messages of type kind. Requires that the node argument have source info.
template <class T,
typename = typename std::enable_if<std::is_base_of<Util::IHasSourceInfo, T>::value>::type,
class... Args>
void info(const int kind, const char *format, const T *node, Args... args) {
auto &context = BaseCompileContext::get();
auto action = context.getDefaultInfoDiagnosticAction();
context.errorReporter().diagnose(action, kind, format, "", node, args...);
}

/// The const ref variant of the above
template <class T,
typename = typename std::enable_if<std::is_base_of<Util::IHasSourceInfo, T>::value>::type,
class... Args>
void info(const int kind, const char *format, const T &node, Args... args) {
::info(kind, format, &node, std::forward<Args>(args)...);
}

/// Report info messages of type kind, for messages that do not have a node.
/// These will not be filtered
template <typename... Args>
void info(const int kind, const char *format, Args... args) {
auto &context = BaseCompileContext::get();
auto action = context.getDefaultInfoDiagnosticAction();
context.errorReporter().diagnose(action, kind, format, "", std::forward<Args>(args)...);
}

/**
* Trigger a diagnostic message.
*
Expand Down
9 changes: 8 additions & 1 deletion lib/error_catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ const int ErrorType::WARN_DUPLICATE_PRIORITIES = 1021;
const int ErrorType::WARN_ENTRIES_OUT_OF_ORDER = 1022;
const int ErrorType::WARN_MAX_WARNINGS = 2142;

// ------ Info message -----------
const int ErrorType::INFO_INFERRED = WARN_MAX_WARNINGS + 1;
const int ErrorType::INFO_MAX_INFOS = 3999;

// map from errorCode to ErrorSig
std::map<int, cstring> ErrorCatalog::errorCatalog = {
// Errors
Expand Down Expand Up @@ -111,4 +115,7 @@ std::map<int, cstring> ErrorCatalog::errorCatalog = {
{ErrorType::WARN_IGNORE, "ignore"},
{ErrorType::WARN_INVALID_HEADER, "invalid_header"},
{ErrorType::WARN_DUPLICATE_PRIORITIES, "duplicate_priorities"},
{ErrorType::WARN_ENTRIES_OUT_OF_ORDER, "entries_out_of_priority_order"}};
{ErrorType::WARN_ENTRIES_OUT_OF_ORDER, "entries_out_of_priority_order"},

// Info messages
{ErrorType::INFO_INFERRED, "inferred"}};
6 changes: 6 additions & 0 deletions lib/error_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ class ErrorType {
static const int WARN_ENTRIES_OUT_OF_ORDER; // entries with priorities out of order

static const int WARN_MAX_WARNINGS;

// -------- Info messages -------------
// info messages as initially defined with a format string
static const int INFO_INFERRED; // information inferred by compiler

static const int INFO_MAX_INFOS;
};

class ErrorCatalog {
Expand Down
5 changes: 5 additions & 0 deletions lib/error_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ std::string ErrorMessage::getPrefix() const {
p = "warning: ";
else
p = "[--Wwarn=" + p + "] warning: ";
} else if (type == MessageType::Info) {
if (p.empty())
p = "info: ";
else
p = "[--Winfo=" + p + "] info: ";
}
return p;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/error_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ limitations under the License.
* directly and those uses need to call toString() on returned object.
*/
struct ErrorMessage {
enum class MessageType : std::size_t { None, Error, Warning };
enum class MessageType : std::size_t { None, Error, Warning, Info };

MessageType type = MessageType::None;
std::string prefix = ""; /// Typically error/warning type from catalog
Expand Down
32 changes: 28 additions & 4 deletions lib/error_reporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ limitations under the License.
/// An action to take when a diagnostic message is triggered.
enum class DiagnosticAction {
Ignore, /// Take no action and continue compilation.
Info, /// Print an info message and continue compilation.
Warn, /// Print a warning and continue compilation.
Error /// Print an error and signal that compilation should be aborted.
};
Expand All @@ -35,8 +36,9 @@ enum class DiagnosticAction {
// Some compatibility for printf-style arguments is also supported.
class ErrorReporter {
protected:
unsigned int errorCount;
unsigned int infoCount;
unsigned int warningCount;
unsigned int errorCount;
unsigned int maxErrorCount; /// the maximum number of errors that we print before fail

std::ostream *outputstream;
Expand Down Expand Up @@ -72,9 +74,11 @@ class ErrorReporter {

public:
ErrorReporter()
: errorCount(0),
: infoCount(0),
warningCount(0),
errorCount(0),
maxErrorCount(20),
defaultInfoDiagnosticAction(DiagnosticAction::Info),
defaultWarningDiagnosticAction(DiagnosticAction::Warn) {
outputstream = &std::cerr;
}
Expand Down Expand Up @@ -138,7 +142,14 @@ class ErrorReporter {
if (action == DiagnosticAction::Ignore) return;

ErrorMessage::MessageType msgType = ErrorMessage::MessageType::None;
if (action == DiagnosticAction::Warn) {
if (action == DiagnosticAction::Info) {
// Avoid burying errors in a pile of info messages:
// don't emit any more info messages if we've emitted errors.
if (errorCount > 0) return;

infoCount++;
msgType = ErrorMessage::MessageType::Info;
} else if (action == DiagnosticAction::Warn) {
// Avoid burying errors in a pile of warnings: don't emit any more warnings if we've
// emitted errors.
if (errorCount > 0) return;
Expand Down Expand Up @@ -171,9 +182,11 @@ class ErrorReporter {

unsigned getWarningCount() const { return warningCount; }

unsigned getInfoCount() const { return infoCount; }

/// @return the number of diagnostics (warnings and errors) encountered
/// in the current CompileContext.
unsigned getDiagnosticCount() const { return errorCount + warningCount; }
unsigned getDiagnosticCount() const { return errorCount + warningCount + infoCount; }

void setOutputStream(std::ostream *stream) { outputstream = stream; }

Expand Down Expand Up @@ -241,7 +254,18 @@ class ErrorReporter {
defaultWarningDiagnosticAction = action;
}

/// @return the default diagnostic action for calls to `::info()`.
DiagnosticAction getDefaultInfoDiagnosticAction() { return defaultInfoDiagnosticAction; }

/// set the default diagnostic action for calls to `::info()`.
void setDefaultInfoDiagnosticAction(DiagnosticAction action) {
defaultInfoDiagnosticAction = action;
}

private:
/// The default diagnostic action for calls to `::info()`.
DiagnosticAction defaultInfoDiagnosticAction;

/// The default diagnostic action for calls to `::warning()`.
DiagnosticAction defaultWarningDiagnosticAction;

Expand Down

0 comments on commit d79e2e8

Please sign in to comment.