Add a FatalUserError macro to help print user-caused errors. (#668)

This commit is contained in:
Jon Meow
2021-07-21 12:38:56 -07:00
committed by GitHub
parent f3cbfc04c6
commit 034f3600e3
15 changed files with 102 additions and 26 deletions
+1
View File
@@ -30,6 +30,7 @@ cc_library(
deps = [
"//common:indirect_value",
"//common:ostream",
"//executable_semantics/common:error",
],
)
+5 -3
View File
@@ -4,6 +4,8 @@
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/common/error.h"
namespace Carbon {
auto Expression::GetIdentifierExpression() const
@@ -166,9 +168,9 @@ auto Expression::MakeTupleLiteral(int line_num,
for (auto& arg : args) {
if (arg.name == "") {
if (seen_named_member) {
llvm::errs() << line_num
<< ": positional members must come before named members\n";
exit(-1);
FatalUserError()
<< line_num
<< ": positional members must come before named members";
}
arg.name = std::to_string(i);
++i;
+18
View File
@@ -4,6 +4,24 @@
package(default_visibility = ["//executable_semantics:__subpackages__"])
cc_library(
name = "error",
hdrs = ["error.h"],
deps = [
"@llvm-project//llvm:Support",
],
)
cc_test(
name = "error_test",
srcs = ["error_test.cpp"],
deps = [
":error",
"@llvm-project//llvm:gtest",
"@llvm-project//llvm:gtest_main",
],
)
cc_library(
name = "tracing_flag",
srcs = ["tracing_flag.cpp"],
+38
View File
@@ -0,0 +1,38 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef EXECUTABLE_SEMANTICS_COMMON_ERROR_H_
#define EXECUTABLE_SEMANTICS_COMMON_ERROR_H_
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
namespace Carbon {
// Prints an error and exits. This should be used for non-recoverable errors
// with user input.
//
// For example:
// FatalUserError() << "Input is not valid!";
class FatalUserError {
public:
FatalUserError() { llvm::errs() << "ERROR: "; }
~FatalUserError() {
// Finish with a newline.
llvm::errs() << "\n";
exit(-1);
}
// Forward output to llvm::errs.
template <typename T>
FatalUserError& operator<<(const T& message) {
llvm::errs() << message;
return *this;
}
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_COMMON_ERROR_H_
@@ -0,0 +1,15 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "executable_semantics/common/error.h"
#include "gtest/gtest.h"
namespace Carbon {
TEST(ErrorTest, FatalUserError) {
ASSERT_DEATH({ FatalUserError() << "test"; }, "ERROR: test\n");
}
} // namespace Carbon
@@ -11,6 +11,7 @@
#include <vector>
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/common/error.h"
#include "executable_semantics/common/tracing_flag.h"
#include "executable_semantics/interpreter/interpreter.h"
@@ -19,20 +20,18 @@ namespace Carbon {
void ExpectType(int line_num, const std::string& context, const Value* expected,
const Value* actual) {
if (!TypeEqual(expected, actual)) {
llvm::errs() << line_num << ": type error in " << context << "\n"
<< "expected: " << *expected << "\n"
<< "actual: " << *actual << "\n";
exit(-1);
FatalUserError() << line_num << ": type error in " << context << "\n"
<< "expected: " << *expected << "\n"
<< "actual: " << *actual;
}
}
void ExpectPointerType(int line_num, const std::string& context,
const Value* actual) {
if (actual->tag() != ValKind::PointerType) {
llvm::errs() << line_num << ": type error in " << context << "\n"
<< "expected a pointer type\n"
<< "actual: " << *actual << "\n";
exit(-1);
FatalUserError() << line_num << ": type error in " << context << "\n"
<< "expected a pointer type\n"
<< "actual: " << *actual;
}
}
+2
View File
@@ -29,9 +29,11 @@ cc_library(
],
deps = [
":paren_contents",
"//common:check",
"//common:ostream",
"//executable_semantics/ast:declaration",
"//executable_semantics/ast:expression",
"//executable_semantics/common:error",
"//executable_semantics/common:tracing_flag",
"//executable_semantics/interpreter",
"//executable_semantics/interpreter:typecheck",
+6 -8
View File
@@ -6,6 +6,8 @@
#include <iostream>
#include "common/check.h"
#include "executable_semantics/common/error.h"
#include "executable_semantics/common/tracing_flag.h"
#include "executable_semantics/syntax/parse_and_lex_context.h"
#include "executable_semantics/syntax/parser.h"
@@ -21,9 +23,8 @@ auto parse(const std::string& input_file_name)
-> std::variant<AST, SyntaxErrorCode> {
yyin = fopen(input_file_name.c_str(), "r");
if (yyin == nullptr) {
std::cerr << "Error opening '" << input_file_name
<< "': " << std::strerror(errno) << std::endl;
exit(1);
FatalUserError() << "Error opening '" << input_file_name
<< "': " << std::strerror(errno);
}
std::optional<AST> parsed_input = std::nullopt;
@@ -38,11 +39,8 @@ auto parse(const std::string& input_file_name)
return syntax_error_code;
}
if (parsed_input == std::nullopt) {
std::cerr << "Internal error: parser validated syntax yet didn't produce "
"an AST.\n";
exit(1);
}
CHECK(parsed_input != std::nullopt)
<< "parser validated syntax yet didn't produce an AST.";
return *parsed_input;
}
+1 -1
View File
@@ -1,2 +1,2 @@
5: positional members must come before named members
ERROR: 5: positional members must come before named members
EXIT CODE: 255
+1 -1
View File
@@ -1,4 +1,4 @@
7: type error in initializer of variable
ERROR: 7: type error in initializer of variable
expected: Int
actual: Bool
EXIT CODE: 255
+1 -1
View File
@@ -1,4 +1,4 @@
10: type error in return
ERROR: 10: type error in return
expected: ()
actual: Int
EXIT CODE: 255
+1 -1
View File
@@ -1,2 +1,2 @@
6: positional members must come before named members
ERROR: 6: positional members must come before named members
EXIT CODE: 255
+1 -1
View File
@@ -1,4 +1,4 @@
8: type error in pattern variable
ERROR: 8: type error in pattern variable
expected: (x = Int, y = Int)
actual: (y = Int, x = Int)
EXIT CODE: 255
+1 -1
View File
@@ -1,4 +1,4 @@
8: type error in ==
ERROR: 8: type error in ==
expected: (0 = Int, 1 = Int)
actual: (0 = Int)
EXIT CODE: 255