mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:54:41 +01:00
Prefix most macro names with CARBON_ (#1232)
I'm doing this to avoid macro name conflicts, following https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros: "If you do export a macro from a header, it must have a globally unique name. To achieve this, it must be named with a prefix consisting of your project's namespace name (but upper case)." Commands run: ``` sed -i 's/\(DCHECK\|CHECK\|FATAL\|MAKE_UNIQUE_NAME\|MAKE_UNIQUE_NAME_IMPL\|RAW_EXITING_STREAM\|RETURN_IF_ERROR\|RETURN_IF_ERROR_IMPL\|ASSIGN_OR_RETURN\|ASSIGN_OR_RETURN_IMPL\|DIAGNOSTIC_KIND\|RETURN_IF_STACK_LIMITED\)(/CARBON_\1(/g' $(git ls-files *.cpp *.h *.lpp *.ypp *.def ':!third_party') sed -i 's/#undef DIAGNOSTIC_KIND/#undef CARBON_DIAGNOSTIC_KIND/' toolchain/diagnostics/diagnostic_registry.def ``` Note this isn't *quite* everything, but it's intended to be a large pass at everything: ``` ╚╡git grep '#define ' *.cpp *.h *.lpp *.ypp *.def ':!third_party' | grep -v '#define CARBON' | grep -v _H_ explorer/syntax/lexer.lpp: #define YY_USER_ACTION \ explorer/syntax/lexer.lpp: #define SIMPLE_TOKEN(name) \ explorer/syntax/lexer.lpp: #define ARG_TOKEN(name, arg) \ explorer/syntax/parse_and_lex_context.h:#define YY_DECL \ migrate_cpp/cpp_refactoring/var_decl.cpp:#define ABSTRACT_TYPE(Class, Base) migrate_cpp/cpp_refactoring/var_decl.cpp:#define TYPE(Class, Base) \ ``` We may in particular want to do a pass to clean up #ifdef guards and make them be CARBON_ rooted.
This commit is contained in:
+13
-12
@@ -12,7 +12,7 @@ namespace Carbon {
|
||||
// Raw exiting stream. This should be used when building other forms of exiting
|
||||
// macros like those below. It evaluates to a temporary `ExitingStream` object
|
||||
// that can be manipulated, streamed into, and then will exit the program.
|
||||
#define RAW_EXITING_STREAM() \
|
||||
#define CARBON_RAW_EXITING_STREAM() \
|
||||
Carbon::Internal::ExitingStream::Helper() | Carbon::Internal::ExitingStream()
|
||||
|
||||
// Checks the given condition, and if it's false, prints a stack, streams the
|
||||
@@ -20,29 +20,30 @@ namespace Carbon {
|
||||
// a bug in the application.
|
||||
//
|
||||
// For example:
|
||||
// CHECK(is_valid) << "Data is not valid!";
|
||||
#define CHECK(condition) \
|
||||
// CARBON_CHECK(is_valid) << "Data is not valid!";
|
||||
#define CARBON_CHECK(condition) \
|
||||
(condition) ? (void)0 \
|
||||
: RAW_EXITING_STREAM() \
|
||||
: CARBON_RAW_EXITING_STREAM() \
|
||||
<< "CHECK failure at " << __FILE__ << ":" << __LINE__ \
|
||||
<< ": " #condition \
|
||||
<< Carbon::Internal::ExitingStream::AddSeparator()
|
||||
|
||||
// DCHECK calls CHECK in debug mode, and does nothing otherwise.
|
||||
#ifndef NDEBUG
|
||||
#define DCHECK(condition) CHECK(condition)
|
||||
#define CARBON_DCHECK(condition) CARBON_CHECK(condition)
|
||||
#else
|
||||
#define DCHECK(condition) CHECK(true || (condition))
|
||||
#define CARBON_DCHECK(condition) CARBON_CHECK(true || (condition))
|
||||
#endif
|
||||
|
||||
// This is similar to CHECK, but is unconditional. Writing FATAL() is clearer
|
||||
// than CHECK(false) because it avoids confusion about control flow.
|
||||
// This is similar to CHECK, but is unconditional. Writing CARBON_FATAL() is
|
||||
// clearer than CARBON_CHECK(false) because it avoids confusion about control
|
||||
// flow.
|
||||
//
|
||||
// For example:
|
||||
// FATAL() << "Unreachable!";
|
||||
#define FATAL() \
|
||||
RAW_EXITING_STREAM() << "FATAL failure at " << __FILE__ << ":" << __LINE__ \
|
||||
<< ": "
|
||||
// CARBON_FATAL() << "Unreachable!";
|
||||
#define CARBON_FATAL() \
|
||||
CARBON_RAW_EXITING_STREAM() \
|
||||
<< "FATAL failure at " << __FILE__ << ":" << __LINE__ << ": "
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
namespace Carbon::Testing {
|
||||
namespace {
|
||||
|
||||
TEST(CheckTest, CheckTrue) { CHECK(true); }
|
||||
TEST(CheckTest, CheckTrue) { CARBON_CHECK(true); }
|
||||
|
||||
TEST(CheckTest, CheckFalse) {
|
||||
// TODO: figure out why we can't use \\d+ instead of .+ in these patterns.
|
||||
ASSERT_DEATH({ CHECK(false); },
|
||||
ASSERT_DEATH({ CARBON_CHECK(false); },
|
||||
"Stack trace:\n"
|
||||
".+\n"
|
||||
"CHECK failure at common/check_test.cpp:.+: false\n");
|
||||
@@ -25,12 +25,12 @@ TEST(CheckTest, CheckTrueCallbackNotUsed) {
|
||||
called = true;
|
||||
return "called";
|
||||
};
|
||||
CHECK(true) << callback();
|
||||
CARBON_CHECK(true) << callback();
|
||||
EXPECT_FALSE(called);
|
||||
}
|
||||
|
||||
TEST(CheckTest, CheckFalseMessage) {
|
||||
ASSERT_DEATH({ CHECK(false) << "msg"; },
|
||||
ASSERT_DEATH({ CARBON_CHECK(false) << "msg"; },
|
||||
"CHECK failure at common/check_test.cpp:.+: false: msg\n");
|
||||
}
|
||||
|
||||
@@ -38,15 +38,15 @@ TEST(CheckTest, CheckOutputForms) {
|
||||
const char msg[] = "msg";
|
||||
std::string str = "str";
|
||||
int i = 1;
|
||||
CHECK(true) << msg << str << i << 0;
|
||||
CARBON_CHECK(true) << msg << str << i << 0;
|
||||
}
|
||||
|
||||
TEST(CheckTest, Fatal) {
|
||||
ASSERT_DEATH({ FATAL() << "msg"; },
|
||||
ASSERT_DEATH({ CARBON_FATAL() << "msg"; },
|
||||
"FATAL failure at common/check_test.cpp:.+: msg\n");
|
||||
}
|
||||
|
||||
auto FatalNoReturnRequired() -> int { FATAL() << "msg"; }
|
||||
auto FatalNoReturnRequired() -> int { CARBON_FATAL() << "msg"; }
|
||||
|
||||
TEST(ErrorTest, FatalNoReturnRequired) {
|
||||
ASSERT_DEATH({ FatalNoReturnRequired(); },
|
||||
|
||||
+18
-17
@@ -23,7 +23,7 @@ class [[nodiscard]] Error {
|
||||
public:
|
||||
// Represents an error state.
|
||||
explicit Error(llvm::Twine message) : message_(message.str()) {
|
||||
CHECK(!message_.empty()) << "Errors must have a message.";
|
||||
CARBON_CHECK(!message_.empty()) << "Errors must have a message.";
|
||||
}
|
||||
|
||||
Error(Error&& other) noexcept : message_(std::move(other.message_)) {}
|
||||
@@ -63,39 +63,39 @@ class [[nodiscard]] ErrorOr {
|
||||
// Returns the contained error.
|
||||
// REQUIRES: `ok()` is false.
|
||||
auto error() const& -> const Error& {
|
||||
CHECK(!ok());
|
||||
CARBON_CHECK(!ok());
|
||||
return std::get<Error>(val_);
|
||||
}
|
||||
auto error() && -> Error {
|
||||
CHECK(!ok());
|
||||
CARBON_CHECK(!ok());
|
||||
return std::get<Error>(std::move(val_));
|
||||
}
|
||||
|
||||
// Returns the contained value.
|
||||
// REQUIRES: `ok()` is true.
|
||||
auto operator*() -> T& {
|
||||
CHECK(ok());
|
||||
CARBON_CHECK(ok());
|
||||
return std::get<T>(val_);
|
||||
}
|
||||
|
||||
// Returns the contained value.
|
||||
// REQUIRES: `ok()` is true.
|
||||
auto operator*() const -> const T& {
|
||||
CHECK(ok());
|
||||
CARBON_CHECK(ok());
|
||||
return std::get<T>(val_);
|
||||
}
|
||||
|
||||
// Returns the contained value.
|
||||
// REQUIRES: `ok()` is true.
|
||||
auto operator->() -> T* {
|
||||
CHECK(ok());
|
||||
CARBON_CHECK(ok());
|
||||
return &std::get<T>(val_);
|
||||
}
|
||||
|
||||
// Returns the contained value.
|
||||
// REQUIRES: `ok()` is true.
|
||||
auto operator->() const -> const T* {
|
||||
CHECK(ok());
|
||||
CARBON_CHECK(ok());
|
||||
return &std::get<T>(val_);
|
||||
}
|
||||
|
||||
@@ -135,28 +135,29 @@ class ErrorBuilder {
|
||||
} // namespace Carbon
|
||||
|
||||
// Macro hackery to get a unique variable name.
|
||||
#define MAKE_UNIQUE_NAME_IMPL(a, b, c) a##b##c
|
||||
#define MAKE_UNIQUE_NAME(a, b, c) MAKE_UNIQUE_NAME_IMPL(a, b, c)
|
||||
#define CARBON_MAKE_UNIQUE_NAME_IMPL(a, b, c) a##b##c
|
||||
#define CARBON_MAKE_UNIQUE_NAME(a, b, c) CARBON_MAKE_UNIQUE_NAME_IMPL(a, b, c)
|
||||
|
||||
#define RETURN_IF_ERROR_IMPL(unique_name, expr) \
|
||||
#define CARBON_RETURN_IF_ERROR_IMPL(unique_name, expr) \
|
||||
if (auto unique_name = (expr); /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
!(unique_name).ok()) { \
|
||||
return std::move(unique_name).error(); \
|
||||
}
|
||||
|
||||
#define RETURN_IF_ERROR(expr) \
|
||||
RETURN_IF_ERROR_IMPL( \
|
||||
MAKE_UNIQUE_NAME(_llvm_error_line, __LINE__, __COUNTER__), expr)
|
||||
#define CARBON_RETURN_IF_ERROR(expr) \
|
||||
CARBON_RETURN_IF_ERROR_IMPL( \
|
||||
CARBON_MAKE_UNIQUE_NAME(_llvm_error_line, __LINE__, __COUNTER__), expr)
|
||||
|
||||
#define ASSIGN_OR_RETURN_IMPL(unique_name, var, expr) \
|
||||
#define CARBON_ASSIGN_OR_RETURN_IMPL(unique_name, var, expr) \
|
||||
auto unique_name = (expr); /* NOLINT(bugprone-macro-parentheses) */ \
|
||||
if (!(unique_name).ok()) { \
|
||||
return std::move(unique_name).error(); \
|
||||
} \
|
||||
var = std::move(*(unique_name)); /* NOLINT(bugprone-macro-parentheses) */
|
||||
|
||||
#define ASSIGN_OR_RETURN(var, expr) \
|
||||
ASSIGN_OR_RETURN_IMPL( \
|
||||
MAKE_UNIQUE_NAME(_llvm_expected_line, __LINE__, __COUNTER__), var, expr)
|
||||
#define CARBON_ASSIGN_OR_RETURN(var, expr) \
|
||||
CARBON_ASSIGN_OR_RETURN_IMPL( \
|
||||
CARBON_MAKE_UNIQUE_NAME(_llvm_expected_line, __LINE__, __COUNTER__), \
|
||||
var, expr)
|
||||
|
||||
#endif // COMMON_ERROR_H_
|
||||
|
||||
@@ -51,8 +51,8 @@ TEST(ErrorTest, IndirectErrorOrSuccess) {
|
||||
|
||||
TEST(ErrorTest, ReturnIfErrorNoError) {
|
||||
auto result = []() -> ErrorOr<Success> {
|
||||
RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
CARBON_RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
CARBON_RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
return Success();
|
||||
}();
|
||||
EXPECT_TRUE(result.ok());
|
||||
@@ -60,8 +60,8 @@ TEST(ErrorTest, ReturnIfErrorNoError) {
|
||||
|
||||
TEST(ErrorTest, ReturnIfErrorHasError) {
|
||||
auto result = []() -> ErrorOr<Success> {
|
||||
RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
RETURN_IF_ERROR(ErrorOr<Success>(Error("error")));
|
||||
CARBON_RETURN_IF_ERROR(ErrorOr<Success>(Success()));
|
||||
CARBON_RETURN_IF_ERROR(ErrorOr<Success>(Error("error")));
|
||||
return Success();
|
||||
}();
|
||||
ASSERT_FALSE(result.ok());
|
||||
@@ -70,10 +70,10 @@ TEST(ErrorTest, ReturnIfErrorHasError) {
|
||||
|
||||
TEST(ErrorTest, AssignOrReturnNoError) {
|
||||
auto result = []() -> ErrorOr<int> {
|
||||
ASSIGN_OR_RETURN(int a, ErrorOr<int>(1));
|
||||
ASSIGN_OR_RETURN(const int b, ErrorOr<int>(2));
|
||||
CARBON_ASSIGN_OR_RETURN(int a, ErrorOr<int>(1));
|
||||
CARBON_ASSIGN_OR_RETURN(const int b, ErrorOr<int>(2));
|
||||
int c = 0;
|
||||
ASSIGN_OR_RETURN(c, ErrorOr<int>(3));
|
||||
CARBON_ASSIGN_OR_RETURN(c, ErrorOr<int>(3));
|
||||
return a + b + c;
|
||||
}();
|
||||
ASSERT_TRUE(result.ok());
|
||||
@@ -82,7 +82,7 @@ TEST(ErrorTest, AssignOrReturnNoError) {
|
||||
|
||||
TEST(ErrorTest, AssignOrReturnHasDirectError) {
|
||||
auto result = []() -> ErrorOr<int> {
|
||||
RETURN_IF_ERROR(ErrorOr<int>(Error("error")));
|
||||
CARBON_RETURN_IF_ERROR(ErrorOr<int>(Error("error")));
|
||||
return 0;
|
||||
}();
|
||||
ASSERT_FALSE(result.ok());
|
||||
@@ -90,7 +90,7 @@ TEST(ErrorTest, AssignOrReturnHasDirectError) {
|
||||
|
||||
TEST(ErrorTest, AssignOrReturnHasErrorInExpected) {
|
||||
auto result = []() -> ErrorOr<int> {
|
||||
ASSIGN_OR_RETURN(int a, ErrorOr<int>(Error("error")));
|
||||
CARBON_ASSIGN_OR_RETURN(int a, ErrorOr<int>(Error("error")));
|
||||
return a;
|
||||
}();
|
||||
ASSERT_FALSE(result.ok());
|
||||
|
||||
@@ -80,7 +80,7 @@ auto UnescapeStringLiteral(llvm::StringRef source, bool is_block_string)
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
FATAL() << "\\u is not yet supported in string literals";
|
||||
CARBON_FATAL() << "\\u is not yet supported in string literals";
|
||||
case '\n':
|
||||
if (!is_block_string) {
|
||||
return std::nullopt;
|
||||
|
||||
@@ -163,7 +163,7 @@ void ReturnTerm::Print(llvm::raw_ostream& out) const {
|
||||
out << "-> auto";
|
||||
return;
|
||||
case ReturnKind::Expression:
|
||||
CHECK(type_expression_.has_value());
|
||||
CARBON_CHECK(type_expression_.has_value());
|
||||
out << "-> " << **type_expression_;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class Declaration : public AstNode {
|
||||
// Sets the static type of the declared entity. Can only be called once,
|
||||
// during typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class Declaration : public AstNode {
|
||||
// Sets the value returned by constant_value(). Can only be called once,
|
||||
// during typechecking.
|
||||
void set_constant_value(Nonnull<const Value*> value) {
|
||||
CHECK(!constant_value_.has_value());
|
||||
CARBON_CHECK(!constant_value_.has_value());
|
||||
constant_value_ = value;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,8 @@ void Expression::Print(llvm::raw_ostream& out) const {
|
||||
<< *op.arguments()[1];
|
||||
break;
|
||||
default:
|
||||
FATAL() << "Unexpected argument count: " << op.arguments().size();
|
||||
CARBON_FATAL() << "Unexpected argument count: "
|
||||
<< op.arguments().size();
|
||||
}
|
||||
out << ")";
|
||||
break;
|
||||
|
||||
@@ -46,14 +46,14 @@ class Expression : public AstNode {
|
||||
|
||||
// The static type of this expression. Cannot be called before typechecking.
|
||||
auto static_type() const -> const Value& {
|
||||
CHECK(static_type_.has_value());
|
||||
CARBON_CHECK(static_type_.has_value());
|
||||
return **static_type_;
|
||||
}
|
||||
|
||||
// Sets the static type of this expression. Can only be called once, during
|
||||
// typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ class Expression : public AstNode {
|
||||
// Sets the value category of this expression. Can be called multiple times,
|
||||
// but the argument must have the same value each time.
|
||||
void set_value_category(ValueCategory value_category) {
|
||||
CHECK(!value_category_.has_value() || value_category == *value_category_);
|
||||
CARBON_CHECK(!value_category_.has_value() ||
|
||||
value_category == *value_category_);
|
||||
value_category_ = value_category;
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ class IdentifierExpression : public Expression {
|
||||
// Sets the value returned by value_node. Can be called only once,
|
||||
// during name resolution.
|
||||
void set_value_node(ValueNodeView value_node) {
|
||||
CHECK(!value_node_.has_value());
|
||||
CARBON_CHECK(!value_node_.has_value());
|
||||
value_node_ = std::move(value_node);
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ class FieldAccessExpression : public Expression {
|
||||
|
||||
// Can only be called once, during typechecking.
|
||||
void set_impl(Nonnull<const ImplBinding*> impl) {
|
||||
CHECK(!impl_.has_value());
|
||||
CARBON_CHECK(!impl_.has_value());
|
||||
impl_ = impl;
|
||||
}
|
||||
|
||||
@@ -294,7 +295,7 @@ class StructLiteral : public Expression {
|
||||
std::vector<FieldInitializer> fields)
|
||||
: Expression(AstNodeKind::StructLiteral, loc),
|
||||
fields_(std::move(fields)) {
|
||||
CHECK(!fields_.empty())
|
||||
CARBON_CHECK(!fields_.empty())
|
||||
<< "`{}` is represented as a StructTypeLiteral, not a StructLiteral.";
|
||||
}
|
||||
|
||||
@@ -392,7 +393,7 @@ class CallExpression : public Expression {
|
||||
|
||||
// Can only be called once, during typechecking.
|
||||
void set_impls(const ImplExpMap& impls) {
|
||||
CHECK(impls_.empty());
|
||||
CARBON_CHECK(impls_.empty());
|
||||
impls_ = impls;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class ImplBinding : public AstNode {
|
||||
// Sets the static type of the impl. Can only be called once, during
|
||||
// typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
|
||||
|
||||
@@ -52,14 +52,14 @@ class Pattern : public AstNode {
|
||||
|
||||
// The static type of this pattern. Cannot be called before typechecking.
|
||||
auto static_type() const -> const Value& {
|
||||
CHECK(static_type_.has_value());
|
||||
CARBON_CHECK(static_type_.has_value());
|
||||
return **static_type_;
|
||||
}
|
||||
|
||||
// Sets the static type of this expression. Can only be called once, during
|
||||
// typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class BindingPattern : public Pattern {
|
||||
// Sets the value category of the variable being bound. Can only be called
|
||||
// once during typechecking
|
||||
void set_value_category(ValueCategory vc) {
|
||||
CHECK(!value_category_.has_value());
|
||||
CARBON_CHECK(!value_category_.has_value());
|
||||
value_category_ = vc;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ class GenericBinding : public Pattern {
|
||||
return symbolic_identity_;
|
||||
}
|
||||
void set_symbolic_identity(Nonnull<const Value*> value) {
|
||||
CHECK(!symbolic_identity_.has_value());
|
||||
CARBON_CHECK(!symbolic_identity_.has_value());
|
||||
symbolic_identity_ = value;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ class GenericBinding : public Pattern {
|
||||
}
|
||||
// Set the impl binding.
|
||||
void set_impl_binding(Nonnull<const ImplBinding*> binding) {
|
||||
CHECK(!impl_binding_.has_value());
|
||||
CARBON_CHECK(!impl_binding_.has_value());
|
||||
impl_binding_ = binding;
|
||||
}
|
||||
|
||||
@@ -283,8 +283,8 @@ class AlternativePattern : public Pattern {
|
||||
Nonnull<Expression*> alternative,
|
||||
Nonnull<TuplePattern*> arguments)
|
||||
-> ErrorOr<Nonnull<AlternativePattern*>> {
|
||||
ASSIGN_OR_RETURN(Nonnull<FieldAccessExpression*> field_access,
|
||||
RequireFieldAccess(alternative));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<FieldAccessExpression*> field_access,
|
||||
RequireFieldAccess(alternative));
|
||||
return arena->New<AlternativePattern>(source_loc,
|
||||
&field_access->aggregate(),
|
||||
field_access->field(), arguments);
|
||||
|
||||
@@ -66,7 +66,7 @@ class ReturnTerm {
|
||||
// Sets the value of static_type(). Can only be called once, during
|
||||
// typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class ReturnTerm {
|
||||
|
||||
explicit ReturnTerm(ReturnKind kind, SourceLocation source_loc)
|
||||
: kind_(kind), source_loc_(source_loc) {
|
||||
CHECK(kind != ReturnKind::Expression);
|
||||
CARBON_CHECK(kind != ReturnKind::Expression);
|
||||
}
|
||||
|
||||
explicit ReturnTerm(Nonnull<Expression*> type_expression)
|
||||
|
||||
@@ -188,7 +188,7 @@ class Return : public Statement {
|
||||
|
||||
// Can only be called once, by ResolveControlFlow.
|
||||
void set_function(Nonnull<FunctionDeclaration*> function) {
|
||||
CHECK(!function_.has_value());
|
||||
CARBON_CHECK(!function_.has_value());
|
||||
function_ = function;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class Break : public Statement {
|
||||
|
||||
// Can only be called once, by ResolveControlFlow.
|
||||
void set_loop(Nonnull<const Statement*> loop) {
|
||||
CHECK(!loop_.has_value());
|
||||
CARBON_CHECK(!loop_.has_value());
|
||||
loop_ = loop;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ class Continue : public Statement {
|
||||
|
||||
// Can only be called once, by ResolveControlFlow.
|
||||
void set_loop(Nonnull<const Statement*> loop) {
|
||||
CHECK(!loop_.has_value());
|
||||
CARBON_CHECK(!loop_.has_value());
|
||||
loop_ = loop;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ class Continuation : public Statement {
|
||||
// Sets the static type of the continuation. Can only be called once,
|
||||
// during typechecking.
|
||||
void set_static_type(Nonnull<const Value*> type) {
|
||||
CHECK(!static_type_.has_value());
|
||||
CARBON_CHECK(!static_type_.has_value());
|
||||
static_type_ = type;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ auto StaticScope::Add(std::string name, ValueNodeView entity)
|
||||
auto StaticScope::Resolve(const std::string& name,
|
||||
SourceLocation source_loc) const
|
||||
-> ErrorOr<ValueNodeView> {
|
||||
ASSIGN_OR_RETURN(std::optional<ValueNodeView> result,
|
||||
TryResolve(name, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(std::optional<ValueNodeView> result,
|
||||
TryResolve(name, source_loc));
|
||||
if (!result) {
|
||||
return CompilationError(source_loc) << "could not resolve '" << name << "'";
|
||||
}
|
||||
@@ -40,8 +40,8 @@ auto StaticScope::TryResolve(const std::string& name,
|
||||
}
|
||||
std::optional<ValueNodeView> result;
|
||||
for (Nonnull<const StaticScope*> parent : parent_scopes_) {
|
||||
ASSIGN_OR_RETURN(std::optional<ValueNodeView> parent_result,
|
||||
parent->TryResolve(name, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(std::optional<ValueNodeView> parent_result,
|
||||
parent->TryResolve(name, source_loc));
|
||||
if (parent_result.has_value() && result.has_value() &&
|
||||
*parent_result != *result) {
|
||||
return CompilationError(source_loc)
|
||||
|
||||
@@ -549,7 +549,7 @@ static auto DeclarationToProto(const Declaration& declaration)
|
||||
}
|
||||
|
||||
case DeclarationKind::SelfDeclaration: {
|
||||
FATAL() << "Unreachable SelfDeclaration in DeclarationToProto().";
|
||||
CARBON_FATAL() << "Unreachable SelfDeclaration in DeclarationToProto().";
|
||||
}
|
||||
}
|
||||
return declaration_proto;
|
||||
|
||||
@@ -65,7 +65,7 @@ void ParseAndExecute(const Fuzzing::CompilationUnit& compilation_unit) {
|
||||
}
|
||||
const ErrorOr<std::string> prelude_path =
|
||||
Internal::GetRunfilesFile("carbon/explorer/data/prelude.carbon");
|
||||
CHECK(prelude_path.ok()) << prelude_path.error().message();
|
||||
CARBON_CHECK(prelude_path.ok()) << prelude_path.error().message();
|
||||
AddPrelude(*prelude_path, &arena, &ast->declarations);
|
||||
const ErrorOr<int> result =
|
||||
ExecProgram(&arena, *ast, /*trace_stream=*/std::nullopt);
|
||||
|
||||
@@ -56,7 +56,8 @@ static auto WriteFile(std::string_view s, std::string_view file_name)
|
||||
static auto TextProtoToCarbon(std::string_view input_file_name,
|
||||
std::string_view output_file_name)
|
||||
-> ErrorOr<Success> {
|
||||
ASSIGN_OR_RETURN(const std::string input_contents, ReadFile(input_file_name));
|
||||
CARBON_ASSIGN_OR_RETURN(const std::string input_contents,
|
||||
ReadFile(input_file_name));
|
||||
Fuzzing::Carbon carbon_proto;
|
||||
if (!google::protobuf::TextFormat::ParseFromString(input_contents,
|
||||
&carbon_proto)) {
|
||||
|
||||
@@ -52,18 +52,18 @@ void RuntimeScope::Print(llvm::raw_ostream& out) const {
|
||||
|
||||
void RuntimeScope::Initialize(ValueNodeView value_node,
|
||||
Nonnull<const Value*> value) {
|
||||
CHECK(!value_node.constant_value().has_value());
|
||||
CHECK(value->kind() != Value::Kind::LValue);
|
||||
CARBON_CHECK(!value_node.constant_value().has_value());
|
||||
CARBON_CHECK(value->kind() != Value::Kind::LValue);
|
||||
allocations_.push_back(heap_->AllocateValue(value));
|
||||
auto [it, success] = locals_.insert(
|
||||
{value_node, heap_->arena().New<LValue>(Address(allocations_.back()))});
|
||||
CHECK(success) << "Duplicate definition of " << value_node.base();
|
||||
CARBON_CHECK(success) << "Duplicate definition of " << value_node.base();
|
||||
}
|
||||
|
||||
void RuntimeScope::Merge(RuntimeScope other) {
|
||||
CHECK(heap_ == other.heap_);
|
||||
CARBON_CHECK(heap_ == other.heap_);
|
||||
locals_.merge(other.locals_);
|
||||
CHECK(other.locals_.empty())
|
||||
CARBON_CHECK(other.locals_.empty())
|
||||
<< "Duplicate definition of " << other.locals_.size()
|
||||
<< " names, including " << other.locals_.begin()->first.base();
|
||||
allocations_.insert(allocations_.end(), other.allocations_.begin(),
|
||||
@@ -83,10 +83,10 @@ auto RuntimeScope::Get(ValueNodeView value_node) const
|
||||
|
||||
auto RuntimeScope::Capture(
|
||||
const std::vector<Nonnull<const RuntimeScope*>>& scopes) -> RuntimeScope {
|
||||
CHECK(!scopes.empty());
|
||||
CARBON_CHECK(!scopes.empty());
|
||||
RuntimeScope result(scopes.front()->heap_);
|
||||
for (Nonnull<const RuntimeScope*> scope : scopes) {
|
||||
CHECK(scope->heap_ == result.heap_);
|
||||
CARBON_CHECK(scope->heap_ == result.heap_);
|
||||
for (const auto& entry : scope->locals_) {
|
||||
// Intentionally disregards duplicates later in the vector.
|
||||
result.locals_.insert(entry);
|
||||
|
||||
@@ -97,7 +97,7 @@ class Action {
|
||||
|
||||
// Resets this Action to its initial state.
|
||||
void Clear() {
|
||||
CHECK(!scope_.has_value());
|
||||
CARBON_CHECK(!scope_.has_value());
|
||||
pos_ = 0;
|
||||
results_.clear();
|
||||
}
|
||||
@@ -127,7 +127,7 @@ class Action {
|
||||
// Action is completed or unwound. Can only be called once on a given
|
||||
// Action.
|
||||
void StartScope(RuntimeScope scope) {
|
||||
CHECK(!scope_.has_value());
|
||||
CARBON_CHECK(!scope_.has_value());
|
||||
scope_ = std::move(scope);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ void ActionStack::PrintScopes(llvm::raw_ostream& out) const {
|
||||
|
||||
void ActionStack::Start(std::unique_ptr<Action> action) {
|
||||
result_ = std::nullopt;
|
||||
CHECK(todo_.IsEmpty());
|
||||
CARBON_CHECK(todo_.IsEmpty());
|
||||
todo_.Push(std::move(action));
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void ActionStack::MergeScope(RuntimeScope scope) {
|
||||
globals_->Merge(std::move(scope));
|
||||
return;
|
||||
}
|
||||
FATAL() << "No current scope";
|
||||
CARBON_FATAL() << "No current scope";
|
||||
}
|
||||
|
||||
void ActionStack::InitializeFragment(ContinuationValue::StackFragment& fragment,
|
||||
@@ -118,9 +118,9 @@ auto ActionStack::FinishAction() -> ErrorOr<Success> {
|
||||
case Action::Kind::ExpressionAction:
|
||||
case Action::Kind::LValAction:
|
||||
case Action::Kind::PatternAction:
|
||||
FATAL() << "This kind of action must produce a result: " << *act;
|
||||
CARBON_FATAL() << "This kind of action must produce a result: " << *act;
|
||||
case Action::Kind::ScopeAction:
|
||||
FATAL() << "ScopeAction at top of stack";
|
||||
CARBON_FATAL() << "ScopeAction at top of stack";
|
||||
case Action::Kind::StatementAction:
|
||||
case Action::Kind::DeclarationAction:
|
||||
PopScopes();
|
||||
@@ -134,9 +134,9 @@ auto ActionStack::FinishAction(Nonnull<const Value*> result)
|
||||
switch (act->kind()) {
|
||||
case Action::Kind::StatementAction:
|
||||
case Action::Kind::DeclarationAction:
|
||||
FATAL() << "This kind of Action cannot produce results: " << *act;
|
||||
CARBON_FATAL() << "This kind of Action cannot produce results: " << *act;
|
||||
case Action::Kind::ScopeAction:
|
||||
FATAL() << "ScopeAction at top of stack";
|
||||
CARBON_FATAL() << "ScopeAction at top of stack";
|
||||
case Action::Kind::ExpressionAction:
|
||||
case Action::Kind::LValAction:
|
||||
case Action::Kind::PatternAction:
|
||||
@@ -184,7 +184,7 @@ auto ActionStack::UnwindTo(Nonnull<const Statement*> ast_node)
|
||||
|
||||
auto ActionStack::UnwindPast(Nonnull<const Statement*> ast_node)
|
||||
-> ErrorOr<Success> {
|
||||
RETURN_IF_ERROR(UnwindTo(ast_node));
|
||||
CARBON_RETURN_IF_ERROR(UnwindTo(ast_node));
|
||||
todo_.Pop();
|
||||
PopScopes();
|
||||
return Success();
|
||||
@@ -192,7 +192,7 @@ auto ActionStack::UnwindPast(Nonnull<const Statement*> ast_node)
|
||||
|
||||
auto ActionStack::UnwindPast(Nonnull<const Statement*> ast_node,
|
||||
Nonnull<const Value*> result) -> ErrorOr<Success> {
|
||||
RETURN_IF_ERROR(UnwindPast(ast_node));
|
||||
CARBON_RETURN_IF_ERROR(UnwindPast(ast_node));
|
||||
SetResult(result);
|
||||
return Success();
|
||||
}
|
||||
|
||||
@@ -35,15 +35,15 @@ auto ExecProgram(Nonnull<Arena*> arena, AST ast,
|
||||
if (trace_stream) {
|
||||
**trace_stream << "********** resolving names **********\n";
|
||||
}
|
||||
RETURN_IF_ERROR(ResolveNames(ast));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(ast));
|
||||
if (trace_stream) {
|
||||
**trace_stream << "********** resolving control flow **********\n";
|
||||
}
|
||||
RETURN_IF_ERROR(ResolveControlFlow(ast));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(ast));
|
||||
if (trace_stream) {
|
||||
**trace_stream << "********** type checking **********\n";
|
||||
}
|
||||
RETURN_IF_ERROR(TypeChecker(arena, trace_stream).TypeCheck(ast));
|
||||
CARBON_RETURN_IF_ERROR(TypeChecker(arena, trace_stream).TypeCheck(ast));
|
||||
if (trace_stream) {
|
||||
**trace_stream << "\n";
|
||||
**trace_stream << "********** type checking complete **********\n";
|
||||
|
||||
@@ -23,17 +23,17 @@ auto Heap::AllocateValue(Nonnull<const Value*> v) -> AllocationId {
|
||||
|
||||
auto Heap::Read(const Address& a, SourceLocation source_loc) const
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc));
|
||||
CARBON_RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc));
|
||||
return values_[a.allocation_.index_]->GetField(arena_, a.field_path_,
|
||||
source_loc);
|
||||
}
|
||||
|
||||
auto Heap::Write(const Address& a, Nonnull<const Value*> v,
|
||||
SourceLocation source_loc) -> ErrorOr<Success> {
|
||||
RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc));
|
||||
ASSIGN_OR_RETURN(values_[a.allocation_.index_],
|
||||
values_[a.allocation_.index_]->SetField(
|
||||
arena_, a.field_path_, v, source_loc));
|
||||
CARBON_RETURN_IF_ERROR(this->CheckAlive(a.allocation_, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(values_[a.allocation_.index_],
|
||||
values_[a.allocation_.index_]->SetField(
|
||||
arena_, a.field_path_, v, source_loc));
|
||||
return Success();
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ void Heap::Deallocate(AllocationId allocation) {
|
||||
if (alive_[allocation.index_]) {
|
||||
alive_[allocation.index_] = false;
|
||||
} else {
|
||||
FATAL() << "deallocating an already dead value: "
|
||||
<< *values_[allocation.index_];
|
||||
CARBON_FATAL() << "deallocating an already dead value: "
|
||||
<< *values_[allocation.index_];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ auto ImplScope::Resolve(Nonnull<const Value*> iface_type,
|
||||
Nonnull<const Value*> type, SourceLocation source_loc,
|
||||
const TypeChecker& type_checker) const
|
||||
-> ErrorOr<Nonnull<Expression*>> {
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
std::optional<Nonnull<Expression*>> result,
|
||||
TryResolve(iface_type, type, source_loc, *this, type_checker));
|
||||
if (!result.has_value()) {
|
||||
@@ -54,13 +54,13 @@ auto ImplScope::TryResolve(Nonnull<const Value*> iface_type,
|
||||
const ImplScope& original_scope,
|
||||
const TypeChecker& type_checker) const
|
||||
-> ErrorOr<std::optional<Nonnull<Expression*>>> {
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
std::optional<Nonnull<Expression*>> result,
|
||||
ResolveHere(iface_type, type, source_loc, original_scope, type_checker));
|
||||
for (Nonnull<const ImplScope*> parent : parent_scopes_) {
|
||||
ASSIGN_OR_RETURN(std::optional<Nonnull<Expression*>> parent_result,
|
||||
parent->TryResolve(iface_type, type, source_loc,
|
||||
original_scope, type_checker));
|
||||
CARBON_ASSIGN_OR_RETURN(std::optional<Nonnull<Expression*>> parent_result,
|
||||
parent->TryResolve(iface_type, type, source_loc,
|
||||
original_scope, type_checker));
|
||||
if (parent_result.has_value()) {
|
||||
if (result.has_value()) {
|
||||
return CompilationError(source_loc) << "ambiguous implementations of "
|
||||
@@ -80,7 +80,7 @@ auto ImplScope::ResolveHere(Nonnull<const Value*> iface_type,
|
||||
const TypeChecker& type_checker) const
|
||||
-> ErrorOr<std::optional<Nonnull<Expression*>>> {
|
||||
if (iface_type->kind() != Value::Kind::InterfaceType) {
|
||||
FATAL() << "expected an interface, not " << *iface_type;
|
||||
CARBON_FATAL() << "expected an interface, not " << *iface_type;
|
||||
}
|
||||
const auto& iface = cast<InterfaceType>(*iface_type);
|
||||
std::optional<Nonnull<Expression*>> result = std::nullopt;
|
||||
|
||||
@@ -196,7 +196,7 @@ auto Interpreter::EvalPrim(Operator op,
|
||||
auto Interpreter::CreateStruct(const std::vector<FieldInitializer>& fields,
|
||||
const std::vector<Nonnull<const Value*>>& values)
|
||||
-> Nonnull<const Value*> {
|
||||
CHECK(fields.size() == values.size());
|
||||
CARBON_CHECK(fields.size() == values.size());
|
||||
std::vector<NamedValue> elements;
|
||||
for (size_t i = 0; i < fields.size(); ++i) {
|
||||
elements.push_back({.name = fields[i].name(), .value = values[i]});
|
||||
@@ -216,7 +216,7 @@ auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
|
||||
}
|
||||
switch (p->kind()) {
|
||||
case Value::Kind::BindingPlaceholderValue: {
|
||||
CHECK(bindings.has_value());
|
||||
CARBON_CHECK(bindings.has_value());
|
||||
const auto& placeholder = cast<BindingPlaceholderValue>(*p);
|
||||
if (placeholder.value_node().has_value()) {
|
||||
(*bindings)->Initialize(*placeholder.value_node(), v);
|
||||
@@ -233,7 +233,7 @@ auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
|
||||
case Value::Kind::TupleValue: {
|
||||
const auto& p_tup = cast<TupleValue>(*p);
|
||||
const auto& v_tup = cast<TupleValue>(*v);
|
||||
CHECK(p_tup.elements().size() == v_tup.elements().size());
|
||||
CARBON_CHECK(p_tup.elements().size() == v_tup.elements().size());
|
||||
for (size_t i = 0; i < p_tup.elements().size(); ++i) {
|
||||
if (!PatternMatch(p_tup.elements()[i], v_tup.elements()[i],
|
||||
source_loc, bindings, generic_args,
|
||||
@@ -244,14 +244,15 @@ auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
FATAL() << "expected a tuple value in pattern, not " << *v;
|
||||
CARBON_FATAL() << "expected a tuple value in pattern, not " << *v;
|
||||
}
|
||||
case Value::Kind::StructValue: {
|
||||
const auto& p_struct = cast<StructValue>(*p);
|
||||
const auto& v_struct = cast<StructValue>(*v);
|
||||
CHECK(p_struct.elements().size() == v_struct.elements().size());
|
||||
CARBON_CHECK(p_struct.elements().size() == v_struct.elements().size());
|
||||
for (size_t i = 0; i < p_struct.elements().size(); ++i) {
|
||||
CHECK(p_struct.elements()[i].name == v_struct.elements()[i].name);
|
||||
CARBON_CHECK(p_struct.elements()[i].name ==
|
||||
v_struct.elements()[i].name);
|
||||
if (!PatternMatch(p_struct.elements()[i].value,
|
||||
v_struct.elements()[i].value, source_loc, bindings,
|
||||
generic_args, trace_stream)) {
|
||||
@@ -273,7 +274,8 @@ auto PatternMatch(Nonnull<const Value*> p, Nonnull<const Value*> v,
|
||||
bindings, generic_args, trace_stream);
|
||||
}
|
||||
default:
|
||||
FATAL() << "expected a choice alternative in pattern, not " << *v;
|
||||
CARBON_FATAL() << "expected a choice alternative in pattern, not "
|
||||
<< *v;
|
||||
}
|
||||
case Value::Kind::FunctionType:
|
||||
switch (v->kind()) {
|
||||
@@ -313,11 +315,11 @@ auto Interpreter::StepLvalue() -> ErrorOr<Success> {
|
||||
case ExpressionKind::IdentifierExpression: {
|
||||
// { {x :: C, E, F} :: S, H}
|
||||
// -> { {E(x) :: C, E, F} :: S, H}
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> value,
|
||||
todo_.ValueOfNode(cast<IdentifierExpression>(exp).value_node(),
|
||||
exp.source_loc()));
|
||||
CHECK(isa<LValue>(value)) << *value;
|
||||
CARBON_CHECK(isa<LValue>(value)) << *value;
|
||||
return todo_.FinishAction(value);
|
||||
}
|
||||
case ExpressionKind::FieldAccessExpression: {
|
||||
@@ -358,8 +360,8 @@ auto Interpreter::StepLvalue() -> ErrorOr<Success> {
|
||||
case ExpressionKind::PrimitiveOperatorExpression: {
|
||||
const auto& op = cast<PrimitiveOperatorExpression>(exp);
|
||||
if (op.op() != Operator::Deref) {
|
||||
FATAL() << "Can't treat primitive operator expression as lvalue: "
|
||||
<< exp;
|
||||
CARBON_FATAL()
|
||||
<< "Can't treat primitive operator expression as lvalue: " << exp;
|
||||
}
|
||||
if (act.pos() == 0) {
|
||||
return todo_.Spawn(
|
||||
@@ -387,9 +389,9 @@ auto Interpreter::StepLvalue() -> ErrorOr<Success> {
|
||||
case ExpressionKind::IfExpression:
|
||||
case ExpressionKind::ArrayTypeLiteral:
|
||||
case ExpressionKind::InstantiateImpl:
|
||||
FATAL() << "Can't treat expression as lvalue: " << exp;
|
||||
CARBON_FATAL() << "Can't treat expression as lvalue: " << exp;
|
||||
case ExpressionKind::UnimplementedExpression:
|
||||
FATAL() << "Unimplemented: " << exp;
|
||||
CARBON_FATAL() << "Unimplemented: " << exp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,28 +400,28 @@ auto Interpreter::EvalImplExp(Nonnull<const Expression*> exp) const
|
||||
switch (exp->kind()) {
|
||||
case ExpressionKind::InstantiateImpl: {
|
||||
const InstantiateImpl& inst_impl = cast<InstantiateImpl>(*exp);
|
||||
ASSIGN_OR_RETURN(Nonnull<const Witness*> gen_impl,
|
||||
EvalImplExp(inst_impl.generic_impl()));
|
||||
CARBON_ASSIGN_OR_RETURN(Nonnull<const Witness*> gen_impl,
|
||||
EvalImplExp(inst_impl.generic_impl()));
|
||||
ImplWitnessMap witnesses;
|
||||
for (auto& [bind, impl_exp] : inst_impl.impls()) {
|
||||
ASSIGN_OR_RETURN(witnesses[bind], EvalImplExp(impl_exp));
|
||||
CARBON_ASSIGN_OR_RETURN(witnesses[bind], EvalImplExp(impl_exp));
|
||||
}
|
||||
return arena_->New<Witness>(&gen_impl->declaration(),
|
||||
inst_impl.type_args(), witnesses);
|
||||
}
|
||||
case ExpressionKind::IdentifierExpression: {
|
||||
const auto& ident = cast<IdentifierExpression>(*exp);
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> value,
|
||||
todo_.ValueOfNode(ident.value_node(), ident.source_loc()));
|
||||
if (const auto* lvalue = dyn_cast<LValue>(value)) {
|
||||
ASSIGN_OR_RETURN(value,
|
||||
heap_.Read(lvalue->address(), exp->source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
value, heap_.Read(lvalue->address(), exp->source_loc()));
|
||||
}
|
||||
return cast<Witness>(value);
|
||||
}
|
||||
default: {
|
||||
FATAL() << "EvalImplExp, unexpected expression: " << *exp;
|
||||
CARBON_FATAL() << "EvalImplExp, unexpected expression: " << *exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,11 +431,12 @@ auto Interpreter::InstantiateType(Nonnull<const Value*> type,
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
switch (type->kind()) {
|
||||
case Value::Kind::VariableType: {
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> value,
|
||||
todo_.ValueOfNode(&cast<VariableType>(*type).binding(), source_loc));
|
||||
if (const auto* lvalue = dyn_cast<LValue>(value)) {
|
||||
ASSIGN_OR_RETURN(value, heap_.Read(lvalue->address(), source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(value,
|
||||
heap_.Read(lvalue->address(), source_loc));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -441,12 +444,12 @@ auto Interpreter::InstantiateType(Nonnull<const Value*> type,
|
||||
const auto& class_type = cast<NominalClassType>(*type);
|
||||
BindingMap inst_type_args;
|
||||
for (const auto& [ty_var, ty_arg] : class_type.type_args()) {
|
||||
ASSIGN_OR_RETURN(inst_type_args[ty_var],
|
||||
InstantiateType(ty_arg, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(inst_type_args[ty_var],
|
||||
InstantiateType(ty_arg, source_loc));
|
||||
}
|
||||
std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>> witnesses;
|
||||
for (const auto& [bind, impl_exp] : class_type.impls()) {
|
||||
ASSIGN_OR_RETURN(witnesses[bind], EvalImplExp(impl_exp));
|
||||
CARBON_ASSIGN_OR_RETURN(witnesses[bind], EvalImplExp(impl_exp));
|
||||
}
|
||||
return arena_->New<NominalClassType>(&class_type.declaration(),
|
||||
inst_type_args, witnesses);
|
||||
@@ -493,8 +496,8 @@ auto Interpreter::Convert(Nonnull<const Value*> value,
|
||||
case Value::Kind::TypeOfChoiceType:
|
||||
case Value::Kind::TypeOfParameterizedEntityName:
|
||||
case Value::Kind::StaticArrayType:
|
||||
// TODO: add `CHECK(TypeEqual(type, value->dynamic_type()))`, once we
|
||||
// have Value::dynamic_type.
|
||||
// TODO: add `CARBON_CHECK(TypeEqual(type, value->dynamic_type()))`, once
|
||||
// we have Value::dynamic_type.
|
||||
return value;
|
||||
case Value::Kind::StructValue: {
|
||||
const auto& struct_val = cast<StructValue>(*value);
|
||||
@@ -507,8 +510,9 @@ auto Interpreter::Convert(Nonnull<const Value*> value,
|
||||
destination_struct_type.fields()) {
|
||||
std::optional<Nonnull<const Value*>> old_value =
|
||||
struct_val.FindField(field_name);
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> val,
|
||||
Convert(*old_value, field_type, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> val,
|
||||
Convert(*old_value, field_type, source_loc));
|
||||
new_elements.push_back({.name = field_name, .value = val});
|
||||
}
|
||||
return arena_->New<StructValue>(std::move(new_elements));
|
||||
@@ -516,13 +520,14 @@ auto Interpreter::Convert(Nonnull<const Value*> value,
|
||||
case Value::Kind::NominalClassType: {
|
||||
// Instantiate the `destintation_type` to obtain the runtime
|
||||
// type of the object.
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> inst_dest,
|
||||
InstantiateType(destination_type, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> inst_dest,
|
||||
InstantiateType(destination_type, source_loc));
|
||||
return arena_->New<NominalClassValue>(inst_dest, value);
|
||||
}
|
||||
default:
|
||||
FATAL() << "Can't convert value " << *value << " to type "
|
||||
<< *destination_type;
|
||||
CARBON_FATAL() << "Can't convert value " << *value << " to type "
|
||||
<< *destination_type;
|
||||
}
|
||||
}
|
||||
case Value::Kind::TupleValue: {
|
||||
@@ -540,15 +545,17 @@ auto Interpreter::Convert(Nonnull<const Value*> value,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FATAL() << "Can't convert value " << *value << " to type "
|
||||
<< *destination_type;
|
||||
CARBON_FATAL() << "Can't convert value " << *value << " to type "
|
||||
<< *destination_type;
|
||||
}
|
||||
CHECK(tuple->elements().size() == destination_element_types.size());
|
||||
CARBON_CHECK(tuple->elements().size() ==
|
||||
destination_element_types.size());
|
||||
std::vector<Nonnull<const Value*>> new_elements;
|
||||
for (size_t i = 0; i < tuple->elements().size(); ++i) {
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> val,
|
||||
Convert(tuple->elements()[i],
|
||||
destination_element_types[i], source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> val,
|
||||
Convert(tuple->elements()[i], destination_element_types[i],
|
||||
source_loc));
|
||||
new_elements.push_back(val);
|
||||
}
|
||||
return arena_->New<TupleValue>(std::move(new_elements));
|
||||
@@ -573,9 +580,10 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
case Value::Kind::FunctionValue: {
|
||||
const FunctionValue& fun_val = cast<FunctionValue>(*fun);
|
||||
const FunctionDeclaration& function = fun_val.declaration();
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> converted_args,
|
||||
Convert(arg, &function.param_pattern().static_type(),
|
||||
call.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> converted_args,
|
||||
Convert(arg, &function.param_pattern().static_type(),
|
||||
call.source_loc()));
|
||||
RuntimeScope function_scope(&heap_);
|
||||
// Bring the class type arguments into scope.
|
||||
for (const auto& [bind, val] : fun_val.type_args()) {
|
||||
@@ -593,10 +601,10 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
function_scope.Initialize(impl_bind, witness);
|
||||
}
|
||||
BindingMap generic_args;
|
||||
CHECK(PatternMatch(&function.param_pattern().value(), converted_args,
|
||||
call.source_loc(), &function_scope, generic_args,
|
||||
trace_stream_));
|
||||
CHECK(function.body().has_value())
|
||||
CARBON_CHECK(PatternMatch(&function.param_pattern().value(),
|
||||
converted_args, call.source_loc(),
|
||||
&function_scope, generic_args, trace_stream_));
|
||||
CARBON_CHECK(function.body().has_value())
|
||||
<< "Calling a function that's missing a body";
|
||||
return todo_.Spawn(std::make_unique<StatementAction>(*function.body()),
|
||||
std::move(function_scope));
|
||||
@@ -604,18 +612,19 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
case Value::Kind::BoundMethodValue: {
|
||||
const auto& m = cast<BoundMethodValue>(*fun);
|
||||
const FunctionDeclaration& method = m.declaration();
|
||||
CHECK(method.is_method());
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> converted_args,
|
||||
Convert(arg, &method.param_pattern().static_type(),
|
||||
call.source_loc()));
|
||||
CARBON_CHECK(method.is_method());
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> converted_args,
|
||||
Convert(arg, &method.param_pattern().static_type(),
|
||||
call.source_loc()));
|
||||
RuntimeScope method_scope(&heap_);
|
||||
BindingMap generic_args;
|
||||
CHECK(PatternMatch(&method.me_pattern().value(), m.receiver(),
|
||||
call.source_loc(), &method_scope, generic_args,
|
||||
trace_stream_));
|
||||
CHECK(PatternMatch(&method.param_pattern().value(), converted_args,
|
||||
call.source_loc(), &method_scope, generic_args,
|
||||
trace_stream_));
|
||||
CARBON_CHECK(PatternMatch(&method.me_pattern().value(), m.receiver(),
|
||||
call.source_loc(), &method_scope, generic_args,
|
||||
trace_stream_));
|
||||
CARBON_CHECK(PatternMatch(&method.param_pattern().value(), converted_args,
|
||||
call.source_loc(), &method_scope, generic_args,
|
||||
trace_stream_));
|
||||
// Bring the class type arguments into scope.
|
||||
for (const auto& [bind, val] : m.type_args()) {
|
||||
method_scope.Initialize(bind, val);
|
||||
@@ -625,7 +634,7 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
for (const auto& [impl_bind, witness] : m.witnesses()) {
|
||||
method_scope.Initialize(impl_bind, witness);
|
||||
}
|
||||
CHECK(method.body().has_value())
|
||||
CARBON_CHECK(method.body().has_value())
|
||||
<< "Calling a method that's missing a body";
|
||||
return todo_.Spawn(std::make_unique<StatementAction>(*method.body()),
|
||||
std::move(method_scope));
|
||||
@@ -635,8 +644,8 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
const Declaration& decl = name.declaration();
|
||||
RuntimeScope params_scope(&heap_);
|
||||
BindingMap generic_args;
|
||||
CHECK(PatternMatch(&name.params().value(), arg, call.source_loc(),
|
||||
¶ms_scope, generic_args, trace_stream_));
|
||||
CARBON_CHECK(PatternMatch(&name.params().value(), arg, call.source_loc(),
|
||||
¶ms_scope, generic_args, trace_stream_));
|
||||
switch (decl.kind()) {
|
||||
case DeclarationKind::ClassDeclaration: {
|
||||
switch (phase()) {
|
||||
@@ -660,7 +669,7 @@ auto Interpreter::CallFunction(const CallExpression& call,
|
||||
}
|
||||
}
|
||||
default:
|
||||
FATAL() << "unknown kind of ParameterizedEntityName " << decl;
|
||||
CARBON_FATAL() << "unknown kind of ParameterizedEntityName " << decl;
|
||||
}
|
||||
}
|
||||
default:
|
||||
@@ -768,42 +777,43 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
// -> { { v_f :: C, E, F} : S, H}
|
||||
std::optional<Nonnull<const Witness*>> witness = std::nullopt;
|
||||
if (access.impl().has_value()) {
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
auto witness_addr,
|
||||
todo_.ValueOfNode(*access.impl(), access.source_loc()));
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> witness_value,
|
||||
heap_.Read(llvm::cast<LValue>(witness_addr)->address(),
|
||||
access.source_loc()));
|
||||
witness = cast<Witness>(witness_value);
|
||||
}
|
||||
FieldPath::Component field(access.field(), witness);
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> member,
|
||||
act.results()[0]->GetField(arena_, FieldPath(field),
|
||||
exp.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> member,
|
||||
act.results()[0]->GetField(arena_, FieldPath(field),
|
||||
exp.source_loc()));
|
||||
return todo_.FinishAction(member);
|
||||
}
|
||||
}
|
||||
case ExpressionKind::IdentifierExpression: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
const auto& ident = cast<IdentifierExpression>(exp);
|
||||
// { {x :: C, E, F} :: S, H} -> { {H(E(x)) :: C, E, F} :: S, H}
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> value,
|
||||
todo_.ValueOfNode(ident.value_node(), ident.source_loc()));
|
||||
if (const auto* lvalue = dyn_cast<LValue>(value)) {
|
||||
ASSIGN_OR_RETURN(value,
|
||||
heap_.Read(lvalue->address(), exp.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
value, heap_.Read(lvalue->address(), exp.source_loc()));
|
||||
}
|
||||
return todo_.FinishAction(value);
|
||||
}
|
||||
case ExpressionKind::IntLiteral:
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
||||
return todo_.FinishAction(
|
||||
arena_->New<IntValue>(cast<IntLiteral>(exp).value()));
|
||||
case ExpressionKind::BoolLiteral:
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
||||
return todo_.FinishAction(
|
||||
arena_->New<BoolValue>(cast<BoolLiteral>(exp).value()));
|
||||
@@ -821,8 +831,9 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
} else {
|
||||
// { {v :: op(vs,[]) :: C, E, F} :: S, H}
|
||||
// -> { {eval_prim(op, (vs,v)) :: C, E, F} :: S, H}
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> value,
|
||||
EvalPrim(op.op(), act.results(), exp.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> value,
|
||||
EvalPrim(op.op(), act.results(), exp.source_loc()));
|
||||
return todo_.FinishAction(value);
|
||||
}
|
||||
}
|
||||
@@ -866,7 +877,7 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
return todo_.FinishAction(act.results()[2 + int(num_impls)]);
|
||||
}
|
||||
} else {
|
||||
FATAL() << "in StepExp with Call pos " << act.pos();
|
||||
CARBON_FATAL() << "in StepExp with Call pos " << act.pos();
|
||||
}
|
||||
}
|
||||
case ExpressionKind::IntrinsicExpression: {
|
||||
@@ -886,15 +897,15 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
}
|
||||
}
|
||||
case ExpressionKind::IntTypeLiteral: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<IntType>());
|
||||
}
|
||||
case ExpressionKind::BoolTypeLiteral: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<BoolType>());
|
||||
}
|
||||
case ExpressionKind::TypeTypeLiteral: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<TypeType>());
|
||||
}
|
||||
case ExpressionKind::FunctionTypeLiteral: {
|
||||
@@ -915,16 +926,16 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
}
|
||||
}
|
||||
case ExpressionKind::ContinuationTypeLiteral: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<ContinuationType>());
|
||||
}
|
||||
case ExpressionKind::StringLiteral:
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}
|
||||
return todo_.FinishAction(
|
||||
arena_->New<StringValue>(cast<StringLiteral>(exp).value()));
|
||||
case ExpressionKind::StringTypeLiteral: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<StringType>());
|
||||
}
|
||||
case ExpressionKind::IfExpression: {
|
||||
@@ -943,7 +954,7 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::UnimplementedExpression:
|
||||
FATAL() << "Unimplemented: " << exp;
|
||||
CARBON_FATAL() << "Unimplemented: " << exp;
|
||||
case ExpressionKind::ArrayTypeLiteral: {
|
||||
const auto& array_literal = cast<ArrayTypeLiteral>(exp);
|
||||
if (act.pos() == 0) {
|
||||
@@ -969,7 +980,7 @@ auto Interpreter::StepPattern() -> ErrorOr<Success> {
|
||||
}
|
||||
switch (pattern.kind()) {
|
||||
case PatternKind::AutoPattern: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.FinishAction(arena_->New<AutoType>());
|
||||
}
|
||||
case PatternKind::BindingPattern: {
|
||||
@@ -1007,7 +1018,7 @@ auto Interpreter::StepPattern() -> ErrorOr<Success> {
|
||||
return todo_.Spawn(
|
||||
std::make_unique<PatternAction>(&alternative.arguments()));
|
||||
} else {
|
||||
CHECK(act.pos() == 2);
|
||||
CARBON_CHECK(act.pos() == 2);
|
||||
const auto& choice_type = cast<ChoiceType>(*act.results()[0]);
|
||||
return todo_.FinishAction(arena_->New<AlternativeValue>(
|
||||
alternative.alternative_name(), choice_type.name(),
|
||||
@@ -1056,9 +1067,10 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
auto c = match_stmt.clauses()[clause_num];
|
||||
RuntimeScope matches(&heap_);
|
||||
BindingMap generic_args;
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> val,
|
||||
Convert(act.results()[0], &c.pattern().static_type(),
|
||||
stmt.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> val,
|
||||
Convert(act.results()[0], &c.pattern().static_type(),
|
||||
stmt.source_loc()));
|
||||
if (PatternMatch(&c.pattern().value(), val, stmt.source_loc(), &matches,
|
||||
generic_args, trace_stream_)) {
|
||||
// Ensure we don't process any more clauses.
|
||||
@@ -1078,9 +1090,10 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
return todo_.Spawn(
|
||||
std::make_unique<ExpressionAction>(&cast<While>(stmt).condition()));
|
||||
} else {
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> condition,
|
||||
Convert(act.results().back(), arena_->New<BoolType>(),
|
||||
stmt.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> condition,
|
||||
Convert(act.results().back(), arena_->New<BoolType>(),
|
||||
stmt.source_loc()));
|
||||
if (cast<BoolValue>(*condition).value()) {
|
||||
// { {true :: (while ([]) s) :: C, E, F} :: S, H}
|
||||
// -> { { s :: (while (e) s) :: C, E, F } :: S, H}
|
||||
@@ -1093,13 +1106,13 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
}
|
||||
}
|
||||
case StatementKind::Break: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
// { { break; :: ... :: (while (e) s) :: C, E, F} :: S, H}
|
||||
// -> { { C, E', F} :: S, H}
|
||||
return todo_.UnwindPast(&cast<Break>(stmt).loop());
|
||||
}
|
||||
case StatementKind::Continue: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
// { { continue; :: ... :: (while (e) s) :: C, E, F} :: S, H}
|
||||
// -> { { (while (e) s) :: C, E', F} :: S, H}
|
||||
return todo_.UnwindTo(&cast<Continue>(stmt).loop());
|
||||
@@ -1130,7 +1143,7 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
} else {
|
||||
// { { v :: (x = []) :: C, E, F} :: S, H}
|
||||
// -> { { C, E(x := a), F} :: S, H(a := copy(v))}
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> v,
|
||||
Convert(act.results()[0], &definition.pattern().static_type(),
|
||||
stmt.source_loc()));
|
||||
@@ -1139,8 +1152,8 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
|
||||
RuntimeScope matches(&heap_);
|
||||
BindingMap generic_args;
|
||||
CHECK(PatternMatch(p, v, stmt.source_loc(), &matches, generic_args,
|
||||
trace_stream_))
|
||||
CARBON_CHECK(PatternMatch(p, v, stmt.source_loc(), &matches,
|
||||
generic_args, trace_stream_))
|
||||
<< stmt.source_loc()
|
||||
<< ": internal error in variable definition, match failed";
|
||||
todo_.MergeScope(std::move(matches));
|
||||
@@ -1170,10 +1183,12 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
// { { v :: (a = []) :: C, E, F} :: S, H}
|
||||
// -> { { C, E, F} :: S, H(a := v)}
|
||||
const auto& lval = cast<LValue>(*act.results()[0]);
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> rval,
|
||||
Convert(act.results()[1], &assign.lhs().static_type(),
|
||||
stmt.source_loc()));
|
||||
RETURN_IF_ERROR(heap_.Write(lval.address(), rval, stmt.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> rval,
|
||||
Convert(act.results()[1], &assign.lhs().static_type(),
|
||||
stmt.source_loc()));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
heap_.Write(lval.address(), rval, stmt.source_loc()));
|
||||
return todo_.FinishAction();
|
||||
}
|
||||
}
|
||||
@@ -1184,9 +1199,10 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
return todo_.Spawn(
|
||||
std::make_unique<ExpressionAction>(&cast<If>(stmt).condition()));
|
||||
} else if (act.pos() == 1) {
|
||||
ASSIGN_OR_RETURN(Nonnull<const Value*> condition,
|
||||
Convert(act.results()[0], arena_->New<BoolType>(),
|
||||
stmt.source_loc()));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> condition,
|
||||
Convert(act.results()[0], arena_->New<BoolType>(),
|
||||
stmt.source_loc()));
|
||||
if (cast<BoolValue>(*condition).value()) {
|
||||
// { {true :: if ([]) then_stmt else else_stmt :: C, E, F} ::
|
||||
// S, H}
|
||||
@@ -1215,14 +1231,14 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
// { {v :: return [] :: C, E, F} :: {C', E', F'} :: S, H}
|
||||
// -> { {v :: C', E', F'} :: S, H}
|
||||
const FunctionDeclaration& function = cast<Return>(stmt).function();
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
Nonnull<const Value*> return_value,
|
||||
Convert(act.results()[0], &function.return_term().static_type(),
|
||||
stmt.source_loc()));
|
||||
return todo_.UnwindPast(*function.body(), return_value);
|
||||
}
|
||||
case StatementKind::Continuation: {
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
const auto& continuation = cast<Continuation>(stmt);
|
||||
// Create a continuation object by creating a frame similar the
|
||||
// way one is created in a function call.
|
||||
@@ -1247,7 +1263,7 @@ auto Interpreter::StepStmt() -> ErrorOr<Success> {
|
||||
}
|
||||
}
|
||||
case StatementKind::Await:
|
||||
CHECK(act.pos() == 0);
|
||||
CARBON_CHECK(act.pos() == 0);
|
||||
return todo_.Suspend();
|
||||
}
|
||||
}
|
||||
@@ -1290,22 +1306,22 @@ auto Interpreter::Step() -> ErrorOr<Success> {
|
||||
Action& act = todo_.CurrentAction();
|
||||
switch (act.kind()) {
|
||||
case Action::Kind::LValAction:
|
||||
RETURN_IF_ERROR(StepLvalue());
|
||||
CARBON_RETURN_IF_ERROR(StepLvalue());
|
||||
break;
|
||||
case Action::Kind::ExpressionAction:
|
||||
RETURN_IF_ERROR(StepExp());
|
||||
CARBON_RETURN_IF_ERROR(StepExp());
|
||||
break;
|
||||
case Action::Kind::PatternAction:
|
||||
RETURN_IF_ERROR(StepPattern());
|
||||
CARBON_RETURN_IF_ERROR(StepPattern());
|
||||
break;
|
||||
case Action::Kind::StatementAction:
|
||||
RETURN_IF_ERROR(StepStmt());
|
||||
CARBON_RETURN_IF_ERROR(StepStmt());
|
||||
break;
|
||||
case Action::Kind::DeclarationAction:
|
||||
RETURN_IF_ERROR(StepDeclaration());
|
||||
CARBON_RETURN_IF_ERROR(StepDeclaration());
|
||||
break;
|
||||
case Action::Kind::ScopeAction:
|
||||
FATAL() << "ScopeAction escaped ActionStack";
|
||||
CARBON_FATAL() << "ScopeAction escaped ActionStack";
|
||||
} // switch
|
||||
return Success();
|
||||
}
|
||||
@@ -1317,7 +1333,7 @@ auto Interpreter::RunAllSteps(std::unique_ptr<Action> action)
|
||||
}
|
||||
todo_.Start(std::move(action));
|
||||
while (!todo_.IsEmpty()) {
|
||||
RETURN_IF_ERROR(Step());
|
||||
CARBON_RETURN_IF_ERROR(Step());
|
||||
if (trace_stream_) {
|
||||
PrintState(**trace_stream_);
|
||||
}
|
||||
@@ -1334,7 +1350,7 @@ auto InterpProgram(const AST& ast, Nonnull<Arena*> arena,
|
||||
}
|
||||
|
||||
for (Nonnull<Declaration*> declaration : ast.declarations) {
|
||||
RETURN_IF_ERROR(interpreter.RunAllSteps(
|
||||
CARBON_RETURN_IF_ERROR(interpreter.RunAllSteps(
|
||||
std::make_unique<DeclarationAction>(declaration)));
|
||||
}
|
||||
|
||||
@@ -1342,7 +1358,7 @@ auto InterpProgram(const AST& ast, Nonnull<Arena*> arena,
|
||||
**trace_stream << "********** calling main function **********\n";
|
||||
}
|
||||
|
||||
RETURN_IF_ERROR(interpreter.RunAllSteps(
|
||||
CARBON_RETURN_IF_ERROR(interpreter.RunAllSteps(
|
||||
std::make_unique<ExpressionAction>(*ast.main_call)));
|
||||
|
||||
return cast<IntValue>(*interpreter.result()).value();
|
||||
@@ -1352,7 +1368,7 @@ auto InterpExp(Nonnull<const Expression*> e, Nonnull<Arena*> arena,
|
||||
std::optional<Nonnull<llvm::raw_ostream*>> trace_stream)
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
Interpreter interpreter(Phase::CompileTime, arena, trace_stream);
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
interpreter.RunAllSteps(std::make_unique<ExpressionAction>(e)));
|
||||
return interpreter.result();
|
||||
}
|
||||
@@ -1361,7 +1377,8 @@ auto InterpPattern(Nonnull<const Pattern*> p, Nonnull<Arena*> arena,
|
||||
std::optional<Nonnull<llvm::raw_ostream*>> trace_stream)
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
Interpreter interpreter(Phase::CompileTime, arena, trace_stream);
|
||||
RETURN_IF_ERROR(interpreter.RunAllSteps(std::make_unique<PatternAction>(p)));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
interpreter.RunAllSteps(std::make_unique<PatternAction>(p)));
|
||||
return interpreter.result();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,10 +78,10 @@ static auto ResolveControlFlow(Nonnull<Statement*> statement,
|
||||
return Success();
|
||||
case StatementKind::If: {
|
||||
auto& if_stmt = cast<If>(*statement);
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveControlFlow(&if_stmt.then_block(), loop, function));
|
||||
if (if_stmt.else_block().has_value()) {
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveControlFlow(*if_stmt.else_block(), loop, function));
|
||||
}
|
||||
return Success();
|
||||
@@ -89,25 +89,26 @@ static auto ResolveControlFlow(Nonnull<Statement*> statement,
|
||||
case StatementKind::Block: {
|
||||
auto& block = cast<Block>(*statement);
|
||||
for (auto* block_statement : block.statements()) {
|
||||
RETURN_IF_ERROR(ResolveControlFlow(block_statement, loop, function));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveControlFlow(block_statement, loop, function));
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::While:
|
||||
RETURN_IF_ERROR(ResolveControlFlow(&cast<While>(*statement).body(),
|
||||
statement, function));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(&cast<While>(*statement).body(),
|
||||
statement, function));
|
||||
return Success();
|
||||
case StatementKind::Match: {
|
||||
auto& match = cast<Match>(*statement);
|
||||
for (Match::Clause& clause : match.clauses()) {
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveControlFlow(&clause.statement(), loop, function));
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
case StatementKind::Continuation:
|
||||
RETURN_IF_ERROR(ResolveControlFlow(&cast<Continuation>(*statement).body(),
|
||||
std::nullopt, std::nullopt));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(
|
||||
&cast<Continuation>(*statement).body(), std::nullopt, std::nullopt));
|
||||
return Success();
|
||||
case StatementKind::ExpressionStatement:
|
||||
case StatementKind::Assign:
|
||||
@@ -124,7 +125,7 @@ auto ResolveControlFlow(Nonnull<Declaration*> declaration) -> ErrorOr<Success> {
|
||||
auto& function = cast<FunctionDeclaration>(*declaration);
|
||||
if (function.body().has_value()) {
|
||||
FunctionData data = {.declaration = &function};
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveControlFlow(*function.body(), std::nullopt, &data));
|
||||
}
|
||||
break;
|
||||
@@ -132,21 +133,21 @@ auto ResolveControlFlow(Nonnull<Declaration*> declaration) -> ErrorOr<Success> {
|
||||
case DeclarationKind::ClassDeclaration: {
|
||||
auto& class_decl = cast<ClassDeclaration>(*declaration);
|
||||
for (Nonnull<Declaration*> member : class_decl.members()) {
|
||||
RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::InterfaceDeclaration: {
|
||||
auto& iface_decl = cast<InterfaceDeclaration>(*declaration);
|
||||
for (Nonnull<Declaration*> member : iface_decl.members()) {
|
||||
RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::ImplDeclaration: {
|
||||
auto& impl_decl = cast<ImplDeclaration>(*declaration);
|
||||
for (Nonnull<Declaration*> member : impl_decl.members()) {
|
||||
RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(member));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -161,7 +162,7 @@ auto ResolveControlFlow(Nonnull<Declaration*> declaration) -> ErrorOr<Success> {
|
||||
|
||||
auto ResolveControlFlow(AST& ast) -> ErrorOr<Success> {
|
||||
for (auto declaration : ast.declarations) {
|
||||
RETURN_IF_ERROR(ResolveControlFlow(declaration));
|
||||
CARBON_RETURN_IF_ERROR(ResolveControlFlow(declaration));
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ static auto AddExposedNames(const Declaration& declaration,
|
||||
switch (declaration.kind()) {
|
||||
case DeclarationKind::InterfaceDeclaration: {
|
||||
auto& iface_decl = cast<InterfaceDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(iface_decl.name(), &iface_decl));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
enclosing_scope.Add(iface_decl.name(), &iface_decl));
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::ImplDeclaration: {
|
||||
@@ -36,30 +37,31 @@ static auto AddExposedNames(const Declaration& declaration,
|
||||
}
|
||||
case DeclarationKind::FunctionDeclaration: {
|
||||
auto& func = cast<FunctionDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(func.name(), &func));
|
||||
CARBON_RETURN_IF_ERROR(enclosing_scope.Add(func.name(), &func));
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::ClassDeclaration: {
|
||||
auto& class_decl = cast<ClassDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(class_decl.name(), &class_decl));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
enclosing_scope.Add(class_decl.name(), &class_decl));
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::ChoiceDeclaration: {
|
||||
auto& choice = cast<ChoiceDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(choice.name(), &choice));
|
||||
CARBON_RETURN_IF_ERROR(enclosing_scope.Add(choice.name(), &choice));
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::VariableDeclaration: {
|
||||
auto& var = cast<VariableDeclaration>(declaration);
|
||||
if (var.binding().name() != AnonymousName) {
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
enclosing_scope.Add(var.binding().name(), &var.binding()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DeclarationKind::SelfDeclaration: {
|
||||
auto& self = cast<SelfDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add("Self", &self));
|
||||
CARBON_RETURN_IF_ERROR(enclosing_scope.Add("Self", &self));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -92,74 +94,81 @@ static auto ResolveNames(Expression& expression,
|
||||
switch (expression.kind()) {
|
||||
case ExpressionKind::CallExpression: {
|
||||
auto& call = cast<CallExpression>(expression);
|
||||
RETURN_IF_ERROR(ResolveNames(call.function(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(call.argument(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(call.function(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(call.argument(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::FunctionTypeLiteral: {
|
||||
auto& fun_type = cast<FunctionTypeLiteral>(expression);
|
||||
RETURN_IF_ERROR(ResolveNames(fun_type.parameter(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(fun_type.return_type(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(fun_type.parameter(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(fun_type.return_type(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::FieldAccessExpression:
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(cast<FieldAccessExpression>(expression).aggregate(),
|
||||
enclosing_scope));
|
||||
break;
|
||||
case ExpressionKind::IndexExpression: {
|
||||
auto& index = cast<IndexExpression>(expression);
|
||||
RETURN_IF_ERROR(ResolveNames(index.aggregate(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(index.offset(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(index.aggregate(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(index.offset(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::PrimitiveOperatorExpression:
|
||||
for (Nonnull<Expression*> operand :
|
||||
cast<PrimitiveOperatorExpression>(expression).arguments()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*operand, enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*operand, enclosing_scope));
|
||||
}
|
||||
break;
|
||||
case ExpressionKind::TupleLiteral:
|
||||
for (Nonnull<Expression*> field :
|
||||
cast<TupleLiteral>(expression).fields()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*field, enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*field, enclosing_scope));
|
||||
}
|
||||
break;
|
||||
case ExpressionKind::StructLiteral:
|
||||
for (FieldInitializer& init : cast<StructLiteral>(expression).fields()) {
|
||||
RETURN_IF_ERROR(ResolveNames(init.expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(init.expression(), enclosing_scope));
|
||||
}
|
||||
break;
|
||||
case ExpressionKind::StructTypeLiteral:
|
||||
for (FieldInitializer& init :
|
||||
cast<StructTypeLiteral>(expression).fields()) {
|
||||
RETURN_IF_ERROR(ResolveNames(init.expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(init.expression(), enclosing_scope));
|
||||
}
|
||||
break;
|
||||
case ExpressionKind::IdentifierExpression: {
|
||||
auto& identifier = cast<IdentifierExpression>(expression);
|
||||
ASSIGN_OR_RETURN(
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
const auto value_node,
|
||||
enclosing_scope.Resolve(identifier.name(), identifier.source_loc()));
|
||||
identifier.set_value_node(value_node);
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::IntrinsicExpression:
|
||||
RETURN_IF_ERROR(ResolveNames(cast<IntrinsicExpression>(expression).args(),
|
||||
enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(
|
||||
cast<IntrinsicExpression>(expression).args(), enclosing_scope));
|
||||
break;
|
||||
case ExpressionKind::IfExpression: {
|
||||
auto& if_expr = cast<IfExpression>(expression);
|
||||
RETURN_IF_ERROR(ResolveNames(if_expr.condition(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(if_expr.then_expression(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(if_expr.else_expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(if_expr.condition(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(if_expr.then_expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(if_expr.else_expression(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case ExpressionKind::ArrayTypeLiteral: {
|
||||
auto& array_literal = cast<ArrayTypeLiteral>(expression);
|
||||
RETURN_IF_ERROR(ResolveNames(array_literal.element_type_expression(),
|
||||
enclosing_scope));
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(
|
||||
array_literal.element_type_expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(array_literal.size_expression(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
@@ -184,39 +193,41 @@ static auto ResolveNames(Pattern& pattern, StaticScope& enclosing_scope)
|
||||
switch (pattern.kind()) {
|
||||
case PatternKind::BindingPattern: {
|
||||
auto& binding = cast<BindingPattern>(pattern);
|
||||
RETURN_IF_ERROR(ResolveNames(binding.type(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(binding.type(), enclosing_scope));
|
||||
if (binding.name() != AnonymousName) {
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(binding.name(), &binding));
|
||||
CARBON_RETURN_IF_ERROR(enclosing_scope.Add(binding.name(), &binding));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PatternKind::GenericBinding: {
|
||||
auto& binding = cast<GenericBinding>(pattern);
|
||||
RETURN_IF_ERROR(ResolveNames(binding.type(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(binding.type(), enclosing_scope));
|
||||
if (binding.name() != AnonymousName) {
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(binding.name(), &binding));
|
||||
CARBON_RETURN_IF_ERROR(enclosing_scope.Add(binding.name(), &binding));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PatternKind::TuplePattern:
|
||||
for (Nonnull<Pattern*> field : cast<TuplePattern>(pattern).fields()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*field, enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*field, enclosing_scope));
|
||||
}
|
||||
break;
|
||||
case PatternKind::AlternativePattern: {
|
||||
auto& alternative = cast<AlternativePattern>(pattern);
|
||||
RETURN_IF_ERROR(ResolveNames(alternative.choice_type(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(alternative.arguments(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(alternative.choice_type(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(alternative.arguments(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case PatternKind::ExpressionPattern:
|
||||
RETURN_IF_ERROR(ResolveNames(
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(
|
||||
cast<ExpressionPattern>(pattern).expression(), enclosing_scope));
|
||||
break;
|
||||
case PatternKind::AutoPattern:
|
||||
break;
|
||||
case PatternKind::VarPattern:
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(cast<VarPattern>(pattern).pattern(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
@@ -227,32 +238,35 @@ static auto ResolveNames(Statement& statement, StaticScope& enclosing_scope)
|
||||
-> ErrorOr<Success> {
|
||||
switch (statement.kind()) {
|
||||
case StatementKind::ExpressionStatement:
|
||||
RETURN_IF_ERROR(ResolveNames(
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(
|
||||
cast<ExpressionStatement>(statement).expression(), enclosing_scope));
|
||||
break;
|
||||
case StatementKind::Assign: {
|
||||
auto& assign = cast<Assign>(statement);
|
||||
RETURN_IF_ERROR(ResolveNames(assign.lhs(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(assign.rhs(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(assign.lhs(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(assign.rhs(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case StatementKind::VariableDefinition: {
|
||||
auto& def = cast<VariableDefinition>(statement);
|
||||
RETURN_IF_ERROR(ResolveNames(def.init(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(def.pattern(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(def.init(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(def.pattern(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case StatementKind::If: {
|
||||
auto& if_stmt = cast<If>(statement);
|
||||
RETURN_IF_ERROR(ResolveNames(if_stmt.condition(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(if_stmt.then_block(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(if_stmt.condition(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(if_stmt.then_block(), enclosing_scope));
|
||||
if (if_stmt.else_block().has_value()) {
|
||||
RETURN_IF_ERROR(ResolveNames(**if_stmt.else_block(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(**if_stmt.else_block(), enclosing_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StatementKind::Return:
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(cast<Return>(statement).expression(), enclosing_scope));
|
||||
break;
|
||||
case StatementKind::Block: {
|
||||
@@ -260,38 +274,40 @@ static auto ResolveNames(Statement& statement, StaticScope& enclosing_scope)
|
||||
StaticScope block_scope;
|
||||
block_scope.AddParent(&enclosing_scope);
|
||||
for (Nonnull<Statement*> sub_statement : block.statements()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*sub_statement, block_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*sub_statement, block_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StatementKind::While: {
|
||||
auto& while_stmt = cast<While>(statement);
|
||||
RETURN_IF_ERROR(ResolveNames(while_stmt.condition(), enclosing_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(while_stmt.body(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(while_stmt.condition(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(while_stmt.body(), enclosing_scope));
|
||||
break;
|
||||
}
|
||||
case StatementKind::Match: {
|
||||
auto& match = cast<Match>(statement);
|
||||
RETURN_IF_ERROR(ResolveNames(match.expression(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(match.expression(), enclosing_scope));
|
||||
for (Match::Clause& clause : match.clauses()) {
|
||||
StaticScope clause_scope;
|
||||
clause_scope.AddParent(&enclosing_scope);
|
||||
RETURN_IF_ERROR(ResolveNames(clause.pattern(), clause_scope));
|
||||
RETURN_IF_ERROR(ResolveNames(clause.statement(), clause_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(clause.pattern(), clause_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(clause.statement(), clause_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StatementKind::Continuation: {
|
||||
auto& continuation = cast<Continuation>(statement);
|
||||
RETURN_IF_ERROR(enclosing_scope.Add(continuation.name(), &continuation));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
enclosing_scope.Add(continuation.name(), &continuation));
|
||||
StaticScope continuation_scope;
|
||||
continuation_scope.AddParent(&enclosing_scope);
|
||||
RETURN_IF_ERROR(ResolveNames(cast<Continuation>(statement).body(),
|
||||
continuation_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(cast<Continuation>(statement).body(),
|
||||
continuation_scope));
|
||||
break;
|
||||
}
|
||||
case StatementKind::Run:
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(cast<Run>(statement).argument(), enclosing_scope));
|
||||
break;
|
||||
case StatementKind::Await:
|
||||
@@ -310,14 +326,14 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
StaticScope iface_scope;
|
||||
iface_scope.AddParent(&enclosing_scope);
|
||||
if (iface.params().has_value()) {
|
||||
RETURN_IF_ERROR(ResolveNames(**iface.params(), iface_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(**iface.params(), iface_scope));
|
||||
}
|
||||
RETURN_IF_ERROR(iface_scope.Add("Self", iface.self()));
|
||||
CARBON_RETURN_IF_ERROR(iface_scope.Add("Self", iface.self()));
|
||||
for (Nonnull<Declaration*> member : iface.members()) {
|
||||
RETURN_IF_ERROR(AddExposedNames(*member, iface_scope));
|
||||
CARBON_RETURN_IF_ERROR(AddExposedNames(*member, iface_scope));
|
||||
}
|
||||
for (Nonnull<Declaration*> member : iface.members()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*member, iface_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*member, iface_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -326,24 +342,24 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
StaticScope impl_scope;
|
||||
impl_scope.AddParent(&enclosing_scope);
|
||||
for (Nonnull<GenericBinding*> binding : impl.deduced_parameters()) {
|
||||
RETURN_IF_ERROR(ResolveNames(binding->type(), impl_scope));
|
||||
RETURN_IF_ERROR(impl_scope.Add(binding->name(), binding));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(binding->type(), impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(impl_scope.Add(binding->name(), binding));
|
||||
}
|
||||
RETURN_IF_ERROR(ResolveNames(*impl.impl_type(), impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*impl.impl_type(), impl_scope));
|
||||
// Only add `Self` to the impl_scope if it is not already in the enclosing
|
||||
// scope. Add `Self` after we resolve names for the impl_type, so you
|
||||
// can't write something like `impl Vector(Self) as ...`. Add `Self`
|
||||
// before resolving names in the interface, so you can write something
|
||||
// like `impl VeryLongTypeName as AddWith(Self)`
|
||||
if (!enclosing_scope.Resolve("Self", impl.source_loc()).ok()) {
|
||||
RETURN_IF_ERROR(AddExposedNames(*impl.self(), impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(AddExposedNames(*impl.self(), impl_scope));
|
||||
}
|
||||
RETURN_IF_ERROR(ResolveNames(impl.interface(), impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(impl.interface(), impl_scope));
|
||||
for (Nonnull<Declaration*> member : impl.members()) {
|
||||
RETURN_IF_ERROR(AddExposedNames(*member, impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(AddExposedNames(*member, impl_scope));
|
||||
}
|
||||
for (Nonnull<Declaration*> member : impl.members()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*member, impl_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*member, impl_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -352,19 +368,21 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
StaticScope function_scope;
|
||||
function_scope.AddParent(&enclosing_scope);
|
||||
for (Nonnull<GenericBinding*> binding : function.deduced_parameters()) {
|
||||
RETURN_IF_ERROR(ResolveNames(binding->type(), function_scope));
|
||||
RETURN_IF_ERROR(function_scope.Add(binding->name(), binding));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(binding->type(), function_scope));
|
||||
CARBON_RETURN_IF_ERROR(function_scope.Add(binding->name(), binding));
|
||||
}
|
||||
if (function.is_method()) {
|
||||
RETURN_IF_ERROR(ResolveNames(function.me_pattern(), function_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(function.me_pattern(), function_scope));
|
||||
}
|
||||
RETURN_IF_ERROR(ResolveNames(function.param_pattern(), function_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(function.param_pattern(), function_scope));
|
||||
if (function.return_term().type_expression().has_value()) {
|
||||
RETURN_IF_ERROR(ResolveNames(**function.return_term().type_expression(),
|
||||
function_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(
|
||||
**function.return_term().type_expression(), function_scope));
|
||||
}
|
||||
if (function.body().has_value()) {
|
||||
RETURN_IF_ERROR(ResolveNames(**function.body(), function_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(**function.body(), function_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -372,10 +390,11 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
auto& class_decl = cast<ClassDeclaration>(declaration);
|
||||
StaticScope class_scope;
|
||||
class_scope.AddParent(&enclosing_scope);
|
||||
RETURN_IF_ERROR(class_scope.Add(class_decl.name(), &class_decl));
|
||||
RETURN_IF_ERROR(AddExposedNames(*class_decl.self(), class_scope));
|
||||
CARBON_RETURN_IF_ERROR(class_scope.Add(class_decl.name(), &class_decl));
|
||||
CARBON_RETURN_IF_ERROR(AddExposedNames(*class_decl.self(), class_scope));
|
||||
if (class_decl.type_params().has_value()) {
|
||||
RETURN_IF_ERROR(ResolveNames(**class_decl.type_params(), class_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(**class_decl.type_params(), class_scope));
|
||||
}
|
||||
|
||||
// TODO: Disable unqualified access of members by other members for now.
|
||||
@@ -386,7 +405,7 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
// AddExposedNames(*member, class_scope);
|
||||
// }
|
||||
for (Nonnull<Declaration*> member : class_decl.members()) {
|
||||
RETURN_IF_ERROR(ResolveNames(*member, class_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*member, class_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -397,7 +416,7 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
// need to check for duplicates.
|
||||
std::set<std::string_view> alternative_names;
|
||||
for (Nonnull<AlternativeSignature*> alternative : choice.alternatives()) {
|
||||
RETURN_IF_ERROR(
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(alternative->signature(), enclosing_scope));
|
||||
if (!alternative_names.insert(alternative->name()).second) {
|
||||
return CompilationError(alternative->source_loc())
|
||||
@@ -409,15 +428,16 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
}
|
||||
case DeclarationKind::VariableDeclaration: {
|
||||
auto& var = cast<VariableDeclaration>(declaration);
|
||||
RETURN_IF_ERROR(ResolveNames(var.binding(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(var.binding(), enclosing_scope));
|
||||
if (var.has_initializer()) {
|
||||
RETURN_IF_ERROR(ResolveNames(var.initializer(), enclosing_scope));
|
||||
CARBON_RETURN_IF_ERROR(
|
||||
ResolveNames(var.initializer(), enclosing_scope));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case DeclarationKind::SelfDeclaration: {
|
||||
FATAL() << "Unreachable: resolving names for `Self` declaration";
|
||||
CARBON_FATAL() << "Unreachable: resolving names for `Self` declaration";
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
@@ -426,10 +446,10 @@ static auto ResolveNames(Declaration& declaration, StaticScope& enclosing_scope)
|
||||
auto ResolveNames(AST& ast) -> ErrorOr<Success> {
|
||||
StaticScope file_scope;
|
||||
for (auto declaration : ast.declarations) {
|
||||
RETURN_IF_ERROR(AddExposedNames(*declaration, file_scope));
|
||||
CARBON_RETURN_IF_ERROR(AddExposedNames(*declaration, file_scope));
|
||||
}
|
||||
for (auto declaration : ast.declarations) {
|
||||
RETURN_IF_ERROR(ResolveNames(*declaration, file_scope));
|
||||
CARBON_RETURN_IF_ERROR(ResolveNames(*declaration, file_scope));
|
||||
}
|
||||
return ResolveNames(**ast.main_call, file_scope);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ struct Stack {
|
||||
//
|
||||
// - Requires: !this->IsEmpty()
|
||||
auto Pop() -> T {
|
||||
CHECK(!IsEmpty()) << "Can't pop from empty stack.";
|
||||
CARBON_CHECK(!IsEmpty()) << "Can't pop from empty stack.";
|
||||
auto r = std::move(elements_.back());
|
||||
elements_.pop_back();
|
||||
return r;
|
||||
@@ -42,8 +42,8 @@ struct Stack {
|
||||
//
|
||||
// - Requires: n >= 0 && n <= Count()
|
||||
void Pop(int n) {
|
||||
CHECK(n >= 0) << "Negative pop count disallowed.";
|
||||
CHECK(static_cast<size_t>(n) <= elements_.size())
|
||||
CARBON_CHECK(n >= 0) << "Negative pop count disallowed.";
|
||||
CARBON_CHECK(static_cast<size_t>(n) <= elements_.size())
|
||||
<< "Can only pop as many elements as stack has.";
|
||||
elements_.erase(elements_.end() - n, elements_.end());
|
||||
}
|
||||
@@ -52,7 +52,7 @@ struct Stack {
|
||||
//
|
||||
// - Requires: !this->IsEmpty()
|
||||
auto Top() const -> const T& {
|
||||
CHECK(!IsEmpty()) << "Empty stack has no Top().";
|
||||
CARBON_CHECK(!IsEmpty()) << "Empty stack has no Top().";
|
||||
return elements_.back();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -58,7 +58,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
}
|
||||
}
|
||||
default:
|
||||
FATAL() << "expected Witness, not " << *witness;
|
||||
CARBON_FATAL() << "expected Witness, not " << *witness;
|
||||
}
|
||||
}
|
||||
switch (v->kind()) {
|
||||
@@ -121,7 +121,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
class_type.witnesses());
|
||||
}
|
||||
default:
|
||||
FATAL() << "field access not allowed for value " << *v;
|
||||
CARBON_FATAL() << "field access not allowed for value " << *v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ auto Value::GetField(Nonnull<Arena*> arena, const FieldPath& path,
|
||||
-> ErrorOr<Nonnull<const Value*>> {
|
||||
Nonnull<const Value*> value(this);
|
||||
for (const FieldPath::Component& field : path.components_) {
|
||||
ASSIGN_OR_RETURN(value, GetMember(arena, value, field, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(value, GetMember(arena, value, field, source_loc));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@@ -155,9 +155,9 @@ static auto SetFieldImpl(
|
||||
return RuntimeError(source_loc)
|
||||
<< "field " << (*path_begin).name() << " not in " << *value;
|
||||
}
|
||||
ASSIGN_OR_RETURN(it->value,
|
||||
SetFieldImpl(arena, it->value, path_begin + 1, path_end,
|
||||
field_value, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
it->value, SetFieldImpl(arena, it->value, path_begin + 1, path_end,
|
||||
field_value, source_loc));
|
||||
return arena->New<StructValue>(elements);
|
||||
}
|
||||
case Value::Kind::NominalClassValue: {
|
||||
@@ -173,13 +173,13 @@ static auto SetFieldImpl(
|
||||
return RuntimeError(source_loc) << "index " << (*path_begin).name()
|
||||
<< " out of range in " << *value;
|
||||
}
|
||||
ASSIGN_OR_RETURN(elements[index],
|
||||
SetFieldImpl(arena, elements[index], path_begin + 1,
|
||||
path_end, field_value, source_loc));
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
elements[index], SetFieldImpl(arena, elements[index], path_begin + 1,
|
||||
path_end, field_value, source_loc));
|
||||
return arena->New<TupleValue>(elements);
|
||||
}
|
||||
default:
|
||||
FATAL() << "field access not allowed for value " << *value;
|
||||
CARBON_FATAL() << "field access not allowed for value " << *value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,13 +400,13 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
}
|
||||
|
||||
ContinuationValue::StackFragment::~StackFragment() {
|
||||
CHECK(reversed_todo_.empty())
|
||||
CARBON_CHECK(reversed_todo_.empty())
|
||||
<< "All StackFragments must be empty before the Carbon program ends.";
|
||||
}
|
||||
|
||||
void ContinuationValue::StackFragment::StoreReversed(
|
||||
std::vector<std::unique_ptr<Action>> reversed_todo) {
|
||||
CHECK(reversed_todo_.empty());
|
||||
CARBON_CHECK(reversed_todo_.empty());
|
||||
reversed_todo_ = std::move(reversed_todo);
|
||||
}
|
||||
|
||||
@@ -545,14 +545,14 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2) -> bool {
|
||||
case Value::Kind::BindingPlaceholderValue:
|
||||
case Value::Kind::ContinuationValue:
|
||||
case Value::Kind::ParameterizedEntityName:
|
||||
FATAL() << "TypeEqual used to compare non-type values\n"
|
||||
<< *t1 << "\n"
|
||||
<< *t2;
|
||||
CARBON_FATAL() << "TypeEqual used to compare non-type values\n"
|
||||
<< *t1 << "\n"
|
||||
<< *t2;
|
||||
case Value::Kind::Witness:
|
||||
FATAL() << "TypeEqual: unexpected Witness";
|
||||
CARBON_FATAL() << "TypeEqual: unexpected Witness";
|
||||
break;
|
||||
case Value::Kind::AutoType:
|
||||
FATAL() << "TypeEqual: unexpected AutoType";
|
||||
CARBON_FATAL() << "TypeEqual: unexpected AutoType";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -604,9 +604,10 @@ auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2) -> bool {
|
||||
case Value::Kind::StructValue: {
|
||||
const auto& struct_v1 = cast<StructValue>(*v1);
|
||||
const auto& struct_v2 = cast<StructValue>(*v2);
|
||||
CHECK(struct_v1.elements().size() == struct_v2.elements().size());
|
||||
CARBON_CHECK(struct_v1.elements().size() == struct_v2.elements().size());
|
||||
for (size_t i = 0; i < struct_v1.elements().size(); ++i) {
|
||||
CHECK(struct_v1.elements()[i].name == struct_v2.elements()[i].name);
|
||||
CARBON_CHECK(struct_v1.elements()[i].name ==
|
||||
struct_v2.elements()[i].name);
|
||||
if (!ValueEqual(struct_v1.elements()[i].value,
|
||||
struct_v2.elements()[i].value)) {
|
||||
return false;
|
||||
@@ -621,7 +622,7 @@ auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2) -> bool {
|
||||
GetName(cast<ParameterizedEntityName>(v1)->declaration());
|
||||
std::optional<std::string> name2 =
|
||||
GetName(cast<ParameterizedEntityName>(v2)->declaration());
|
||||
CHECK(name1.has_value() && name2.has_value())
|
||||
CARBON_CHECK(name1.has_value() && name2.has_value())
|
||||
<< "parameterized name refers to unnamed declaration";
|
||||
return *name1 == *name2;
|
||||
}
|
||||
@@ -654,7 +655,8 @@ auto ValueEqual(Nonnull<const Value*> v1, Nonnull<const Value*> v2) -> bool {
|
||||
case Value::Kind::LValue:
|
||||
// TODO: support pointer comparisons once we have a clearer distinction
|
||||
// between pointers and lvalues.
|
||||
FATAL() << "ValueEqual does not support this kind of value: " << *v1;
|
||||
CARBON_FATAL() << "ValueEqual does not support this kind of value: "
|
||||
<< *v1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ class StructValue : public Value {
|
||||
public:
|
||||
explicit StructValue(std::vector<NamedValue> elements)
|
||||
: Value(Kind::StructValue), elements_(std::move(elements)) {
|
||||
CHECK(!elements_.empty())
|
||||
CARBON_CHECK(!elements_.empty())
|
||||
<< "`{}` is represented as a StructType, not a StructValue.";
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ class NominalClassType : public Value {
|
||||
// Construct a non-generic class type.
|
||||
explicit NominalClassType(Nonnull<const ClassDeclaration*> declaration)
|
||||
: Value(Kind::NominalClassType), declaration_(declaration) {
|
||||
CHECK(!declaration->type_params().has_value())
|
||||
CARBON_CHECK(!declaration->type_params().has_value())
|
||||
<< "missing arguments for parameterized class type";
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ class InterfaceType : public Value {
|
||||
public:
|
||||
explicit InterfaceType(Nonnull<const InterfaceDeclaration*> declaration)
|
||||
: Value(Kind::InterfaceType), declaration_(declaration) {
|
||||
CHECK(!declaration->params().has_value())
|
||||
CARBON_CHECK(!declaration->params().has_value())
|
||||
<< "missing arguments for parameterized interface type";
|
||||
}
|
||||
explicit InterfaceType(Nonnull<const InterfaceDeclaration*> declaration,
|
||||
|
||||
+4
-2
@@ -70,11 +70,13 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
}
|
||||
|
||||
Arena arena;
|
||||
ASSIGN_OR_RETURN(AST ast, Parse(&arena, input_file_name, parser_debug));
|
||||
CARBON_ASSIGN_OR_RETURN(AST ast,
|
||||
Parse(&arena, input_file_name, parser_debug));
|
||||
AddPrelude(prelude_file_name, &arena, &ast.declarations);
|
||||
|
||||
// Typecheck and run the parsed program.
|
||||
ASSIGN_OR_RETURN(int return_code, ExecProgram(&arena, ast, trace_stream));
|
||||
CARBON_ASSIGN_OR_RETURN(int return_code,
|
||||
ExecProgram(&arena, ast, trace_stream));
|
||||
// Print the return code to stdout even when we aren't tracing.
|
||||
(trace_stream ? **trace_stream : llvm::outs())
|
||||
<< "result: " << return_code << "\n";
|
||||
|
||||
@@ -30,7 +30,7 @@ class BisonWrap {
|
||||
// Deliberately releases the contained value. Errors if not initialized.
|
||||
// Called directly in parser.ypp when releasing pairs.
|
||||
auto Release() -> T {
|
||||
CHECK(val_.has_value());
|
||||
CARBON_CHECK(val_.has_value());
|
||||
T ret = std::move(*val_);
|
||||
val_.reset();
|
||||
return ret;
|
||||
|
||||
@@ -283,7 +283,7 @@ string_literal \"([^\\\"\n\v\f\r]|\\.)*\"
|
||||
|
||||
{string_literal} {
|
||||
llvm::StringRef str(yytext);
|
||||
CHECK(str.consume_front("\"") && str.consume_back("\""));
|
||||
CARBON_CHECK(str.consume_front("\"") && str.consume_back("\""));
|
||||
std::optional<std::string> unescaped = Carbon::UnescapeStringLiteral(str);
|
||||
if (unescaped == std::nullopt) {
|
||||
return context.RecordSyntaxError(
|
||||
|
||||
@@ -36,7 +36,7 @@ static auto ParseImpl(yyscan_t scanner, Nonnull<Arena*> arena,
|
||||
}
|
||||
|
||||
// Return parse results.
|
||||
CHECK(ast != std::nullopt)
|
||||
CARBON_CHECK(ast != std::nullopt)
|
||||
<< "parser validated syntax yet didn't produce an AST.";
|
||||
return *ast;
|
||||
}
|
||||
|
||||
@@ -300,8 +300,8 @@ primary_expression:
|
||||
| sized_type_literal
|
||||
{
|
||||
int val;
|
||||
CHECK(llvm::to_integer(llvm::StringRef($1).substr(1), val));
|
||||
CHECK($1[0] == 'i' && val == 32)
|
||||
CARBON_CHECK(llvm::to_integer(llvm::StringRef($1).substr(1), val));
|
||||
CARBON_CHECK($1[0] == 'i' && val == 32)
|
||||
<< "Only i32 is supported for now: " << $1;
|
||||
$$ = arena->New<IntTypeLiteral>(context.source_loc());
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ void AddPrelude(std::string_view prelude_file_name, Nonnull<Arena*> arena,
|
||||
if (!parse_result.ok()) {
|
||||
// Try again with tracing, to help diagnose the problem.
|
||||
ErrorOr<AST> trace_parse_result = Parse(arena, prelude_file_name, true);
|
||||
FATAL() << "Failed to parse prelude: "
|
||||
<< trace_parse_result.error().message();
|
||||
CARBON_FATAL() << "Failed to parse prelude: "
|
||||
<< trace_parse_result.error().message();
|
||||
}
|
||||
const auto& prelude = *parse_result;
|
||||
declarations->insert(declarations->begin(), prelude.declarations.begin(),
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Carbon {
|
||||
auto operator<<(llvm::raw_ostream& out, DiagnosticKind kind)
|
||||
-> llvm::raw_ostream& {
|
||||
static constexpr llvm::StringLiteral Names[] = {
|
||||
#define DIAGNOSTIC_KIND(DiagnosticName) #DiagnosticName,
|
||||
#define CARBON_DIAGNOSTIC_KIND(DiagnosticName) #DiagnosticName,
|
||||
#include "toolchain/diagnostics/diagnostic_registry.def"
|
||||
};
|
||||
out << Names[static_cast<int>(kind)];
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Carbon {
|
||||
// long-term, and we also see value to keeping diagnostic format strings close
|
||||
// to the consuming code.
|
||||
enum class DiagnosticKind : int32_t {
|
||||
#define DIAGNOSTIC_KIND(DiagnosticName) DiagnosticName,
|
||||
#define CARBON_DIAGNOSTIC_KIND(DiagnosticName) DiagnosticName,
|
||||
#include "toolchain/diagnostics/diagnostic_registry.def"
|
||||
};
|
||||
|
||||
|
||||
@@ -16,61 +16,61 @@
|
||||
// Lexer diagnostics
|
||||
// ============================================================================
|
||||
|
||||
DIAGNOSTIC_KIND(BinaryRealLiteral)
|
||||
DIAGNOSTIC_KIND(ContentBeforeStringTerminator)
|
||||
DIAGNOSTIC_KIND(DecimalEscapeSequence)
|
||||
DIAGNOSTIC_KIND(EmptyDigitSequence)
|
||||
DIAGNOSTIC_KIND(HexadecimalEscapeMissingDigits)
|
||||
DIAGNOSTIC_KIND(InvalidDigit)
|
||||
DIAGNOSTIC_KIND(InvalidDigitSeparator)
|
||||
DIAGNOSTIC_KIND(InvalidHorizontalWhitespaceInString)
|
||||
DIAGNOSTIC_KIND(IrregularDigitSeparators)
|
||||
DIAGNOSTIC_KIND(MismatchedClosing)
|
||||
DIAGNOSTIC_KIND(MismatchedIndentInString)
|
||||
DIAGNOSTIC_KIND(NoWhitespaceAfterCommentIntroducer)
|
||||
DIAGNOSTIC_KIND(TooManyDigits)
|
||||
DIAGNOSTIC_KIND(TrailingComment)
|
||||
DIAGNOSTIC_KIND(UnicodeEscapeMissingBracedDigits)
|
||||
DIAGNOSTIC_KIND(UnicodeEscapeSurrogate)
|
||||
DIAGNOSTIC_KIND(UnicodeEscapeTooLarge)
|
||||
DIAGNOSTIC_KIND(UnknownBaseSpecifier)
|
||||
DIAGNOSTIC_KIND(UnknownEscapeSequence)
|
||||
DIAGNOSTIC_KIND(UnmatchedClosing)
|
||||
DIAGNOSTIC_KIND(UnrecognizedCharacters)
|
||||
DIAGNOSTIC_KIND(UnterminatedString)
|
||||
DIAGNOSTIC_KIND(WrongRealLiteralExponent)
|
||||
CARBON_DIAGNOSTIC_KIND(BinaryRealLiteral)
|
||||
CARBON_DIAGNOSTIC_KIND(ContentBeforeStringTerminator)
|
||||
CARBON_DIAGNOSTIC_KIND(DecimalEscapeSequence)
|
||||
CARBON_DIAGNOSTIC_KIND(EmptyDigitSequence)
|
||||
CARBON_DIAGNOSTIC_KIND(HexadecimalEscapeMissingDigits)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidDigit)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidDigitSeparator)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidHorizontalWhitespaceInString)
|
||||
CARBON_DIAGNOSTIC_KIND(IrregularDigitSeparators)
|
||||
CARBON_DIAGNOSTIC_KIND(MismatchedClosing)
|
||||
CARBON_DIAGNOSTIC_KIND(MismatchedIndentInString)
|
||||
CARBON_DIAGNOSTIC_KIND(NoWhitespaceAfterCommentIntroducer)
|
||||
CARBON_DIAGNOSTIC_KIND(TooManyDigits)
|
||||
CARBON_DIAGNOSTIC_KIND(TrailingComment)
|
||||
CARBON_DIAGNOSTIC_KIND(UnicodeEscapeMissingBracedDigits)
|
||||
CARBON_DIAGNOSTIC_KIND(UnicodeEscapeSurrogate)
|
||||
CARBON_DIAGNOSTIC_KIND(UnicodeEscapeTooLarge)
|
||||
CARBON_DIAGNOSTIC_KIND(UnknownBaseSpecifier)
|
||||
CARBON_DIAGNOSTIC_KIND(UnknownEscapeSequence)
|
||||
CARBON_DIAGNOSTIC_KIND(UnmatchedClosing)
|
||||
CARBON_DIAGNOSTIC_KIND(UnrecognizedCharacters)
|
||||
CARBON_DIAGNOSTIC_KIND(UnterminatedString)
|
||||
CARBON_DIAGNOSTIC_KIND(WrongRealLiteralExponent)
|
||||
|
||||
// ============================================================================
|
||||
// Parser diagnostics
|
||||
// ============================================================================
|
||||
|
||||
DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace)
|
||||
DIAGNOSTIC_KIND(ExpectedCloseParen)
|
||||
DIAGNOSTIC_KIND(ExpectedCodeBlock)
|
||||
DIAGNOSTIC_KIND(ExpectedExpression)
|
||||
DIAGNOSTIC_KIND(ExpectedFunctionBodyOrSemi)
|
||||
DIAGNOSTIC_KIND(ExpectedFunctionName)
|
||||
DIAGNOSTIC_KIND(ExpectedFunctionParams)
|
||||
DIAGNOSTIC_KIND(ExpectedIdentifierAfterDot)
|
||||
DIAGNOSTIC_KIND(ExpectedParameterName)
|
||||
DIAGNOSTIC_KIND(ExpectedParenAfter)
|
||||
DIAGNOSTIC_KIND(ExpectedSemiAfter)
|
||||
DIAGNOSTIC_KIND(ExpectedSemiAfterExpression)
|
||||
DIAGNOSTIC_KIND(ExpectedStructLiteralField)
|
||||
DIAGNOSTIC_KIND(ExpectedVariableName)
|
||||
DIAGNOSTIC_KIND(OperatorRequiresParentheses)
|
||||
DIAGNOSTIC_KIND(StackLimitExceeded)
|
||||
DIAGNOSTIC_KIND(UnaryOperatorHasWhitespace)
|
||||
DIAGNOSTIC_KIND(UnaryOperatorRequiresWhitespace)
|
||||
DIAGNOSTIC_KIND(UnexpectedTokenAfterListElement)
|
||||
DIAGNOSTIC_KIND(UnexpectedTokenInCodeBlock)
|
||||
DIAGNOSTIC_KIND(UnrecognizedDeclaration)
|
||||
CARBON_DIAGNOSTIC_KIND(BinaryOperatorRequiresWhitespace)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedCloseParen)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedCodeBlock)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedExpression)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedFunctionBodyOrSemi)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedFunctionName)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedFunctionParams)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedIdentifierAfterDot)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedParameterName)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedParenAfter)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedSemiAfter)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedSemiAfterExpression)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedStructLiteralField)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedVariableName)
|
||||
CARBON_DIAGNOSTIC_KIND(OperatorRequiresParentheses)
|
||||
CARBON_DIAGNOSTIC_KIND(StackLimitExceeded)
|
||||
CARBON_DIAGNOSTIC_KIND(UnaryOperatorHasWhitespace)
|
||||
CARBON_DIAGNOSTIC_KIND(UnaryOperatorRequiresWhitespace)
|
||||
CARBON_DIAGNOSTIC_KIND(UnexpectedTokenAfterListElement)
|
||||
CARBON_DIAGNOSTIC_KIND(UnexpectedTokenInCodeBlock)
|
||||
CARBON_DIAGNOSTIC_KIND(UnrecognizedDeclaration)
|
||||
|
||||
// ============================================================================
|
||||
// Other diagnostics
|
||||
// ============================================================================
|
||||
|
||||
// TestDiagnostic is only for unit tests.
|
||||
DIAGNOSTIC_KIND(TestDiagnostic)
|
||||
CARBON_DIAGNOSTIC_KIND(TestDiagnostic)
|
||||
|
||||
#undef DIAGNOSTIC_KIND
|
||||
#undef CARBON_DIAGNOSTIC_KIND
|
||||
|
||||
@@ -78,7 +78,7 @@ auto LexedNumericLiteral::Lex(llvm::StringRef source_text)
|
||||
IsAlnum(source_text[i + 1])) {
|
||||
// This is not possible because we don't update result.exponent after we
|
||||
// see a '+' or '-'.
|
||||
CHECK(!seen_plus_minus) << "should only consume one + or -";
|
||||
CARBON_CHECK(!seen_plus_minus) << "should only consume one + or -";
|
||||
seen_plus_minus = true;
|
||||
continue;
|
||||
}
|
||||
@@ -336,7 +336,8 @@ auto LexedNumericLiteral::Parser::CheckDigitSequence(
|
||||
// correctly positioned.
|
||||
auto LexedNumericLiteral::Parser::CheckDigitSeparatorPlacement(
|
||||
llvm::StringRef text, Radix radix, int num_digit_separators) -> void {
|
||||
DCHECK(std::count(text.begin(), text.end(), '_') == num_digit_separators)
|
||||
CARBON_DCHECK(std::count(text.begin(), text.end(), '_') ==
|
||||
num_digit_separators)
|
||||
<< "given wrong number of digit separators: " << num_digit_separators;
|
||||
|
||||
if (radix == Radix::Binary) {
|
||||
|
||||
@@ -13,19 +13,19 @@ namespace {
|
||||
|
||||
static void BM_Lex_Float(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
CHECK(LexedNumericLiteral::Lex("0.000001"));
|
||||
CARBON_CHECK(LexedNumericLiteral::Lex("0.000001"));
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_Lex_Integer(benchmark::State& state) {
|
||||
for (auto _ : state) {
|
||||
CHECK(LexedNumericLiteral::Lex("1_234_567_890"));
|
||||
CARBON_CHECK(LexedNumericLiteral::Lex("1_234_567_890"));
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_ComputeValue_Float(benchmark::State& state) {
|
||||
auto val = LexedNumericLiteral::Lex("0.000001");
|
||||
CHECK(val);
|
||||
CARBON_CHECK(val);
|
||||
auto emitter = NullDiagnosticEmitter<const char*>();
|
||||
for (auto _ : state) {
|
||||
val->ComputeValue(emitter);
|
||||
@@ -35,7 +35,7 @@ static void BM_ComputeValue_Float(benchmark::State& state) {
|
||||
static void BM_ComputeValue_Integer(benchmark::State& state) {
|
||||
auto val = LexedNumericLiteral::Lex("1_234_567_890");
|
||||
auto emitter = NullDiagnosticEmitter<const char*>();
|
||||
CHECK(val);
|
||||
CARBON_CHECK(val);
|
||||
for (auto _ : state) {
|
||||
val->ComputeValue(emitter);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class NumericLiteralTest : public ::testing::Test {
|
||||
|
||||
auto Lex(llvm::StringRef text) -> LexedNumericLiteral {
|
||||
llvm::Optional<LexedNumericLiteral> result = LexedNumericLiteral::Lex(text);
|
||||
CHECK(result);
|
||||
CARBON_CHECK(result);
|
||||
EXPECT_EQ(result->text(), text);
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ static auto ExpandUnicodeEscapeSequence(LexerDiagnosticEmitter& emitter,
|
||||
static auto ExpandAndConsumeEscapeSequence(LexerDiagnosticEmitter& emitter,
|
||||
llvm::StringRef& content,
|
||||
std::string& result) -> void {
|
||||
CHECK(!content.empty()) << "should have escaped closing delimiter";
|
||||
CARBON_CHECK(!content.empty()) << "should have escaped closing delimiter";
|
||||
char first = content.front();
|
||||
content = content.drop_front(1);
|
||||
|
||||
@@ -343,7 +343,7 @@ static auto ExpandEscapeSequencesAndRemoveIndent(
|
||||
if (IsHorizontalWhitespace(contents.front())) {
|
||||
// Horizontal whitespace other than ` ` is valid only at the end of a
|
||||
// line.
|
||||
CHECK(contents.front() != ' ')
|
||||
CARBON_CHECK(contents.front() != ' ')
|
||||
<< "should not have stopped at a plain space";
|
||||
auto after_space = contents.find_if_not(IsHorizontalWhitespace);
|
||||
if (after_space == llvm::StringRef::npos ||
|
||||
|
||||
@@ -33,7 +33,7 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data,
|
||||
fprintf(stderr, "text: %s\n", token->text().str().c_str());
|
||||
|
||||
// Check multiline flag was computed correctly.
|
||||
CHECK(token->is_multi_line() == token->text().contains('\n'));
|
||||
CARBON_CHECK(token->is_multi_line() == token->text().contains('\n'));
|
||||
|
||||
volatile auto value =
|
||||
token->ComputeValue(NullDiagnosticEmitter<const char*>());
|
||||
|
||||
@@ -21,7 +21,7 @@ class StringLiteralTest : public ::testing::Test {
|
||||
|
||||
auto Lex(llvm::StringRef text) -> LexedStringLiteral {
|
||||
llvm::Optional<LexedStringLiteral> result = LexedStringLiteral::Lex(text);
|
||||
CHECK(result);
|
||||
CARBON_CHECK(result);
|
||||
EXPECT_EQ(result->text(), text);
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class SingleTokenDiagnosticTranslator
|
||||
: token_(token) {}
|
||||
|
||||
auto GetLocation(const char* pos) -> DiagnosticLocation override {
|
||||
CHECK(StringRefContainsPointer(token_, pos))
|
||||
CARBON_CHECK(StringRefContainsPointer(token_, pos))
|
||||
<< "invalid diagnostic location";
|
||||
llvm::StringRef prefix = token_.take_front(pos - token_.begin());
|
||||
auto [before_last_newline, this_line] = prefix.rsplit('\n');
|
||||
|
||||
@@ -56,7 +56,7 @@ auto TokenKind::GetClosingSymbol() const -> TokenKind {
|
||||
#include "toolchain/lexer/token_registry.def"
|
||||
};
|
||||
auto result = Table[static_cast<int>(kind_value_)];
|
||||
CHECK(result != Error()) << "Only opening symbols are valid!";
|
||||
CARBON_CHECK(result != Error()) << "Only opening symbols are valid!";
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ auto TokenKind::GetOpeningSymbol() const -> TokenKind {
|
||||
#include "toolchain/lexer/token_registry.def"
|
||||
};
|
||||
auto result = Table[static_cast<int>(kind_value_)];
|
||||
CHECK(result != Error()) << "Only closing symbols are valid!";
|
||||
CARBON_CHECK(result != Error()) << "Only closing symbols are valid!";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ class TokenizedBuffer::Lexer {
|
||||
default:
|
||||
// If we find a non-whitespace character without exhausting the
|
||||
// buffer, return true to continue lexing.
|
||||
CHECK(!IsSpace(source_text.front()));
|
||||
CARBON_CHECK(!IsSpace(source_text.front()));
|
||||
if (whitespace_start != source_text.begin()) {
|
||||
NoteWhitespace();
|
||||
}
|
||||
@@ -176,7 +176,8 @@ class TokenizedBuffer::Lexer {
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(source_text.empty()) << "Cannot reach here w/o finishing the text!";
|
||||
CARBON_CHECK(source_text.empty())
|
||||
<< "Cannot reach here w/o finishing the text!";
|
||||
// Update the line length as this is also the end of a line.
|
||||
current_line_info_->length = current_column_;
|
||||
return false;
|
||||
@@ -218,8 +219,8 @@ class TokenizedBuffer::Lexer {
|
||||
buffer_.literal_int_storage_.size();
|
||||
buffer_.literal_int_storage_.push_back(std::move(value.mantissa));
|
||||
buffer_.literal_int_storage_.push_back(std::move(value.exponent));
|
||||
CHECK(buffer_.GetRealLiteral(token).IsDecimal() ==
|
||||
(value.radix == LexedNumericLiteral::Radix::Decimal));
|
||||
CARBON_CHECK(buffer_.GetRealLiteral(token).IsDecimal() ==
|
||||
(value.radix == LexedNumericLiteral::Radix::Decimal));
|
||||
return token;
|
||||
},
|
||||
[&](LexedNumericLiteral::UnrecoverableError) {
|
||||
@@ -415,7 +416,8 @@ class TokenizedBuffer::Lexer {
|
||||
"Closing symbol does not match most recent opening symbol.");
|
||||
token_emitter_.Emit(opening_token, MismatchedClosing);
|
||||
|
||||
CHECK(!buffer_.tokens().empty()) << "Must have a prior opening token!";
|
||||
CARBON_CHECK(!buffer_.tokens().empty())
|
||||
<< "Must have a prior opening token!";
|
||||
Token prev_token = buffer_.tokens().end()[-1];
|
||||
|
||||
// TODO: do a smarter backwards scan for where to put the closing
|
||||
@@ -455,7 +457,8 @@ class TokenizedBuffer::Lexer {
|
||||
// Take the valid characters off the front of the source buffer.
|
||||
llvm::StringRef identifier_text =
|
||||
source_text.take_while([](char c) { return IsAlnum(c) || c == '_'; });
|
||||
CHECK(!identifier_text.empty()) << "Must have at least one character!";
|
||||
CARBON_CHECK(!identifier_text.empty())
|
||||
<< "Must have at least one character!";
|
||||
int identifier_column = current_column_;
|
||||
current_column_ += identifier_text.size();
|
||||
source_text = source_text.drop_front(identifier_text.size());
|
||||
@@ -567,7 +570,7 @@ auto TokenizedBuffer::Lex(SourceBuffer& source, DiagnosticConsumer& consumer)
|
||||
if (!result) {
|
||||
result = lexer.LexError(source_text);
|
||||
}
|
||||
CHECK(result) << "No token was lexed.";
|
||||
CARBON_CHECK(result) << "No token was lexed.";
|
||||
}
|
||||
|
||||
// The end-of-file token is always considered to be whitespace.
|
||||
@@ -620,7 +623,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
|
||||
int64_t token_start = line_info.start + token_info.column;
|
||||
llvm::Optional<LexedNumericLiteral> relexed_token =
|
||||
LexedNumericLiteral::Lex(source_->text().substr(token_start));
|
||||
CHECK(relexed_token) << "Could not reform numeric literal token.";
|
||||
CARBON_CHECK(relexed_token) << "Could not reform numeric literal token.";
|
||||
return relexed_token->text();
|
||||
}
|
||||
|
||||
@@ -631,7 +634,7 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
|
||||
int64_t token_start = line_info.start + token_info.column;
|
||||
llvm::Optional<LexedStringLiteral> relexed_token =
|
||||
LexedStringLiteral::Lex(source_->text().substr(token_start));
|
||||
CHECK(relexed_token) << "Could not reform string literal token.";
|
||||
CARBON_CHECK(relexed_token) << "Could not reform string literal token.";
|
||||
return relexed_token->text();
|
||||
}
|
||||
|
||||
@@ -649,14 +652,14 @@ auto TokenizedBuffer::GetTokenText(Token token) const -> llvm::StringRef {
|
||||
return llvm::StringRef();
|
||||
}
|
||||
|
||||
CHECK(token_info.kind == TokenKind::Identifier())
|
||||
CARBON_CHECK(token_info.kind == TokenKind::Identifier())
|
||||
<< "Only identifiers have stored text!";
|
||||
return GetIdentifierText(token_info.id);
|
||||
}
|
||||
|
||||
auto TokenizedBuffer::GetIdentifier(Token token) const -> Identifier {
|
||||
auto& token_info = GetTokenInfo(token);
|
||||
CHECK(token_info.kind == TokenKind::Identifier())
|
||||
CARBON_CHECK(token_info.kind == TokenKind::Identifier())
|
||||
<< "The token must be an identifier!";
|
||||
return token_info.id;
|
||||
}
|
||||
@@ -664,14 +667,14 @@ auto TokenizedBuffer::GetIdentifier(Token token) const -> Identifier {
|
||||
auto TokenizedBuffer::GetIntegerLiteral(Token token) const
|
||||
-> const llvm::APInt& {
|
||||
auto& token_info = GetTokenInfo(token);
|
||||
CHECK(token_info.kind == TokenKind::IntegerLiteral())
|
||||
CARBON_CHECK(token_info.kind == TokenKind::IntegerLiteral())
|
||||
<< "The token must be an integer literal!";
|
||||
return literal_int_storage_[token_info.literal_index];
|
||||
}
|
||||
|
||||
auto TokenizedBuffer::GetRealLiteral(Token token) const -> RealLiteralValue {
|
||||
auto& token_info = GetTokenInfo(token);
|
||||
CHECK(token_info.kind == TokenKind::RealLiteral())
|
||||
CARBON_CHECK(token_info.kind == TokenKind::RealLiteral())
|
||||
<< "The token must be a real literal!";
|
||||
|
||||
// Note that every real literal is at least three characters long, so we can
|
||||
@@ -687,7 +690,7 @@ auto TokenizedBuffer::GetRealLiteral(Token token) const -> RealLiteralValue {
|
||||
|
||||
auto TokenizedBuffer::GetStringLiteral(Token token) const -> llvm::StringRef {
|
||||
auto& token_info = GetTokenInfo(token);
|
||||
CHECK(token_info.kind == TokenKind::StringLiteral())
|
||||
CARBON_CHECK(token_info.kind == TokenKind::StringLiteral())
|
||||
<< "The token must be a string literal!";
|
||||
return literal_string_storage_[token_info.literal_index];
|
||||
}
|
||||
@@ -695,7 +698,7 @@ auto TokenizedBuffer::GetStringLiteral(Token token) const -> llvm::StringRef {
|
||||
auto TokenizedBuffer::GetTypeLiteralSize(Token token) const
|
||||
-> const llvm::APInt& {
|
||||
auto& token_info = GetTokenInfo(token);
|
||||
CHECK(token_info.kind.IsSizedTypeLiteral())
|
||||
CARBON_CHECK(token_info.kind.IsSizedTypeLiteral())
|
||||
<< "The token must be a sized type literal!";
|
||||
return literal_int_storage_[token_info.literal_index];
|
||||
}
|
||||
@@ -703,7 +706,7 @@ auto TokenizedBuffer::GetTypeLiteralSize(Token token) const
|
||||
auto TokenizedBuffer::GetMatchedClosingToken(Token opening_token) const
|
||||
-> Token {
|
||||
auto& opening_token_info = GetTokenInfo(opening_token);
|
||||
CHECK(opening_token_info.kind.IsOpeningSymbol())
|
||||
CARBON_CHECK(opening_token_info.kind.IsOpeningSymbol())
|
||||
<< "The token must be an opening group symbol!";
|
||||
return opening_token_info.closing_token;
|
||||
}
|
||||
@@ -711,7 +714,7 @@ auto TokenizedBuffer::GetMatchedClosingToken(Token opening_token) const
|
||||
auto TokenizedBuffer::GetMatchedOpeningToken(Token closing_token) const
|
||||
-> Token {
|
||||
auto& closing_token_info = GetTokenInfo(closing_token);
|
||||
CHECK(closing_token_info.kind.IsClosingSymbol())
|
||||
CARBON_CHECK(closing_token_info.kind.IsClosingSymbol())
|
||||
<< "The token must be an closing group symbol!";
|
||||
return closing_token_info.opening_token;
|
||||
}
|
||||
@@ -756,7 +759,7 @@ auto TokenizedBuffer::PrintWidths::Widen(const PrintWidths& widths) -> void {
|
||||
//
|
||||
// This routine requires its argument to be *non-negative*.
|
||||
static auto ComputeDecimalPrintedWidth(int number) -> int {
|
||||
CHECK(number >= 0) << "Negative numbers are not supported.";
|
||||
CARBON_CHECK(number >= 0) << "Negative numbers are not supported.";
|
||||
if (number == 0) {
|
||||
return 1;
|
||||
}
|
||||
@@ -887,7 +890,7 @@ auto TokenizedBuffer::TokenIterator::Print(llvm::raw_ostream& output) const
|
||||
|
||||
auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
|
||||
const char* loc) -> DiagnosticLocation {
|
||||
CHECK(StringRefContainsPointer(buffer_->source_->text(), loc))
|
||||
CARBON_CHECK(StringRefContainsPointer(buffer_->source_->text(), loc))
|
||||
<< "location not within buffer";
|
||||
int64_t offset = loc - buffer_->source_->text().begin();
|
||||
|
||||
@@ -901,7 +904,7 @@ auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
|
||||
line_it == buffer_->line_infos_.end();
|
||||
|
||||
// Step back one line to find the line containing the given position.
|
||||
CHECK(line_it != buffer_->line_infos_.begin())
|
||||
CARBON_CHECK(line_it != buffer_->line_infos_.begin())
|
||||
<< "location precedes the start of the first line";
|
||||
--line_it;
|
||||
int line_number = line_it - buffer_->line_infos_.begin();
|
||||
|
||||
@@ -39,11 +39,11 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data,
|
||||
// token stream.
|
||||
for (TokenizedBuffer::Token token : buffer.tokens()) {
|
||||
int line_number = buffer.GetLineNumber(token);
|
||||
CHECK(line_number > 0) << "Invalid line number!";
|
||||
CHECK(line_number < INT_MAX) << "Invalid line number!";
|
||||
CARBON_CHECK(line_number > 0) << "Invalid line number!";
|
||||
CARBON_CHECK(line_number < INT_MAX) << "Invalid line number!";
|
||||
int column_number = buffer.GetColumnNumber(token);
|
||||
CHECK(column_number > 0) << "Invalid line number!";
|
||||
CHECK(column_number < INT_MAX) << "Invalid line number!";
|
||||
CARBON_CHECK(column_number > 0) << "Invalid line number!";
|
||||
CARBON_CHECK(column_number < INT_MAX) << "Invalid line number!";
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -131,8 +131,8 @@ MATCHER_P(HasTokens, raw_all_expected, "") {
|
||||
matches = false;
|
||||
}
|
||||
|
||||
CHECK(!expected.string_contents ||
|
||||
expected.kind == TokenKind::StringLiteral());
|
||||
CARBON_CHECK(!expected.string_contents ||
|
||||
expected.kind == TokenKind::StringLiteral());
|
||||
if (expected.string_contents && actual_kind == TokenKind::StringLiteral()) {
|
||||
llvm::StringRef actual_contents = buffer.GetStringLiteral(token);
|
||||
if (actual_contents != *expected.string_contents) {
|
||||
|
||||
@@ -101,7 +101,7 @@ inline auto ExpectedNodesMatcher::MatchAndExplain(
|
||||
}
|
||||
|
||||
if (expected_node.skip_subtree) {
|
||||
CHECK(expected_node.children.empty())
|
||||
CARBON_CHECK(expected_node.children.empty())
|
||||
<< "Must not skip an expected subtree while specifying expected "
|
||||
"children!";
|
||||
nodes_it = llvm::reverse(tree.postorder(n)).end();
|
||||
@@ -138,7 +138,7 @@ inline auto ExpectedNodesMatcher::MatchAndExplain(
|
||||
// subtrees. Instead, we need to check that we successfully processed all of
|
||||
// the actual tree and consumed all of the expected tree.
|
||||
if (nodes_it != nodes_end) {
|
||||
CHECK(expected_node_stack.empty())
|
||||
CARBON_CHECK(expected_node_stack.empty())
|
||||
<< "If we have unmatched nodes in the input tree, should only finish "
|
||||
"having fully processed expected tree.";
|
||||
output << "\nFinished processing expected nodes and there are still "
|
||||
@@ -193,7 +193,7 @@ inline auto ExpectedNodesMatcher::DescribeTo(std::ostream* output_ptr) const
|
||||
}
|
||||
|
||||
if (!expected_node.children.empty()) {
|
||||
CHECK(!expected_node.skip_subtree)
|
||||
CARBON_CHECK(!expected_node.skip_subtree)
|
||||
<< "Must not have children and skip a subtree!";
|
||||
output << ", children: [\n";
|
||||
for (const ExpectedNode& child_expected_node :
|
||||
@@ -209,7 +209,7 @@ inline auto ExpectedNodesMatcher::DescribeTo(std::ostream* output_ptr) const
|
||||
// we pop up.
|
||||
output << "}";
|
||||
if (!expected_node_stack.empty()) {
|
||||
CHECK(depth >= expected_node_stack.back().second)
|
||||
CARBON_CHECK(depth >= expected_node_stack.back().second)
|
||||
<< "Cannot have an increase in depth on a leaf node!";
|
||||
// The distance we need to pop is the difference in depth.
|
||||
int pop_depth = depth - expected_node_stack.back().second;
|
||||
|
||||
@@ -37,7 +37,7 @@ auto ParseTree::postorder() const -> llvm::iterator_range<PostorderIterator> {
|
||||
|
||||
auto ParseTree::postorder(Node n) const
|
||||
-> llvm::iterator_range<PostorderIterator> {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
// The postorder ends after this node, the root, and begins at the start of
|
||||
// its subtree.
|
||||
int end_index = n.index_ + 1;
|
||||
@@ -48,7 +48,7 @@ auto ParseTree::postorder(Node n) const
|
||||
|
||||
auto ParseTree::children(Node n) const
|
||||
-> llvm::iterator_range<SiblingIterator> {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
int end_index = n.index_ - node_impls_[n.index_].subtree_size;
|
||||
return {SiblingIterator(*this, Node(n.index_ - 1)),
|
||||
SiblingIterator(*this, Node(end_index))};
|
||||
@@ -61,22 +61,22 @@ auto ParseTree::roots() const -> llvm::iterator_range<SiblingIterator> {
|
||||
}
|
||||
|
||||
auto ParseTree::node_has_error(Node n) const -> bool {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
return node_impls_[n.index_].has_error;
|
||||
}
|
||||
|
||||
auto ParseTree::node_kind(Node n) const -> ParseNodeKind {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
return node_impls_[n.index_].kind;
|
||||
}
|
||||
|
||||
auto ParseTree::node_token(Node n) const -> TokenizedBuffer::Token {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
return node_impls_[n.index_].token;
|
||||
}
|
||||
|
||||
auto ParseTree::GetNodeText(Node n) const -> llvm::StringRef {
|
||||
CHECK(n.is_valid());
|
||||
CARBON_CHECK(n.is_valid());
|
||||
return tokens_->GetTokenText(node_impls_[n.index_].token);
|
||||
}
|
||||
|
||||
@@ -126,12 +126,12 @@ auto ParseTree::Print(llvm::raw_ostream& output) const -> void {
|
||||
}
|
||||
|
||||
// This node is finished, so close it up.
|
||||
CHECK(n_impl.subtree_size == 1)
|
||||
CARBON_CHECK(n_impl.subtree_size == 1)
|
||||
<< "Subtree size must always be a positive integer!";
|
||||
output << "}";
|
||||
|
||||
int next_depth = node_stack.empty() ? 0 : node_stack.back().second;
|
||||
CHECK(next_depth <= depth) << "Cannot have the next depth increase!";
|
||||
CARBON_CHECK(next_depth <= depth) << "Cannot have the next depth increase!";
|
||||
for (int close_children_count : llvm::seq(0, depth - next_depth)) {
|
||||
(void)close_children_count;
|
||||
output << "]}";
|
||||
|
||||
@@ -42,7 +42,8 @@ extern "C" int LLVMFuzzerTestOneInput(const unsigned char* data,
|
||||
|
||||
// In the absence of parse errors, we should have exactly as many nodes as
|
||||
// tokens.
|
||||
CHECK(tree.size() == tokens.size()) << "Unexpected number of tree nodes!";
|
||||
CARBON_CHECK(tree.size() == tokens.size())
|
||||
<< "Unexpected number of tree nodes!";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ class ParseTree::Parser::ScopedStackStep {
|
||||
|
||||
// Encapsulates checking the stack and erroring if needed. This should be called
|
||||
// at the start of every parse function.
|
||||
#define RETURN_IF_STACK_LIMITED(error_return_expr) \
|
||||
ScopedStackStep scoped_stack_step(this); \
|
||||
if (!scoped_stack_step.VerifyUnderLimit()) { \
|
||||
return (error_return_expr); \
|
||||
#define CARBON_RETURN_IF_STACK_LIMITED(error_return_expr) \
|
||||
ScopedStackStep scoped_stack_step(this); \
|
||||
if (!scoped_stack_step.VerifyUnderLimit()) { \
|
||||
return (error_return_expr); \
|
||||
}
|
||||
|
||||
// A relative location for characters in errors.
|
||||
@@ -83,10 +83,11 @@ ParseTree::Parser::Parser(ParseTree& tree_arg, TokenizedBuffer& tokens_arg,
|
||||
emitter_(emitter),
|
||||
position_(tokens_.tokens().begin()),
|
||||
end_(tokens_.tokens().end()) {
|
||||
CHECK(std::find_if(position_, end_,
|
||||
[&](TokenizedBuffer::Token t) {
|
||||
return tokens_.GetKind(t) == TokenKind::EndOfFile();
|
||||
}) != end_)
|
||||
CARBON_CHECK(std::find_if(position_, end_,
|
||||
[&](TokenizedBuffer::Token t) {
|
||||
return tokens_.GetKind(t) ==
|
||||
TokenKind::EndOfFile();
|
||||
}) != end_)
|
||||
<< "No EndOfFileToken in token buffer.";
|
||||
}
|
||||
|
||||
@@ -110,16 +111,17 @@ auto ParseTree::Parser::Parse(TokenizedBuffer& tokens,
|
||||
|
||||
parser.AddLeafNode(ParseNodeKind::FileEnd(), *parser.position_);
|
||||
|
||||
CHECK(tree.Verify()) << "Parse tree built but does not verify!";
|
||||
CARBON_CHECK(tree.Verify()) << "Parse tree built but does not verify!";
|
||||
return tree;
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::Consume(TokenKind kind) -> TokenizedBuffer::Token {
|
||||
CHECK(kind != TokenKind::EndOfFile()) << "Cannot consume the EOF token!";
|
||||
CHECK(NextTokenIs(kind)) << "The current token is the wrong kind!";
|
||||
CARBON_CHECK(kind != TokenKind::EndOfFile())
|
||||
<< "Cannot consume the EOF token!";
|
||||
CARBON_CHECK(NextTokenIs(kind)) << "The current token is the wrong kind!";
|
||||
TokenizedBuffer::Token t = *position_;
|
||||
++position_;
|
||||
CHECK(position_ != end_)
|
||||
CARBON_CHECK(position_ != end_)
|
||||
<< "Reached end of tokens without finding EOF token.";
|
||||
return t;
|
||||
}
|
||||
@@ -196,9 +198,9 @@ auto ParseTree::Parser::SkipMatchingGroup() -> bool {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::SkipTo(TokenizedBuffer::Token t) -> void {
|
||||
CHECK(t >= *position_) << "Tried to skip backwards.";
|
||||
CARBON_CHECK(t >= *position_) << "Tried to skip backwards.";
|
||||
position_ = TokenizedBuffer::TokenIterator(t);
|
||||
CHECK(position_ != end_) << "Skipped past EOF.";
|
||||
CARBON_CHECK(position_ != end_) << "Skipped past EOF.";
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::FindNextOf(
|
||||
@@ -325,7 +327,7 @@ auto ParseTree::Parser::ParseList(TokenKind open, TokenKind close,
|
||||
|
||||
auto end_of_element = FindNextOf({TokenKind::Comma(), close});
|
||||
// The lexer guarantees that parentheses are balanced.
|
||||
CHECK(end_of_element) << "missing matching `)` for `(`";
|
||||
CARBON_CHECK(end_of_element) << "missing matching `)` for `(`";
|
||||
SkipTo(*end_of_element);
|
||||
}
|
||||
|
||||
@@ -347,7 +349,7 @@ auto ParseTree::Parser::ParseList(TokenKind open, TokenKind close,
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParsePattern(PatternKind kind) -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
if (NextTokenIs(TokenKind::Identifier()) &&
|
||||
tokens_.GetKind(*(position_ + 1)) == TokenKind::Colon()) {
|
||||
// identifier `:` type
|
||||
@@ -378,12 +380,12 @@ auto ParseTree::Parser::ParsePattern(PatternKind kind) -> llvm::Optional<Node> {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseFunctionParameter() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
return ParsePattern(PatternKind::Parameter);
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseFunctionSignature() -> bool {
|
||||
RETURN_IF_STACK_LIMITED(false);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(false);
|
||||
auto start = GetSubtreeStartPosition();
|
||||
|
||||
auto params = ParseParenList(
|
||||
@@ -410,7 +412,7 @@ auto ParseTree::Parser::ParseFunctionSignature() -> bool {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseCodeBlock() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
llvm::Optional<TokenizedBuffer::Token> maybe_open_curly =
|
||||
ConsumeIf(TokenKind::OpenCurlyBrace());
|
||||
if (!maybe_open_curly) {
|
||||
@@ -454,7 +456,7 @@ auto ParseTree::Parser::ParseFunctionDeclaration() -> Node {
|
||||
return AddNode(ParseNodeKind::FunctionDeclaration(), function_intro_token,
|
||||
start, /*has_error=*/true);
|
||||
};
|
||||
RETURN_IF_STACK_LIMITED(add_error_function_node());
|
||||
CARBON_RETURN_IF_STACK_LIMITED(add_error_function_node());
|
||||
|
||||
auto handle_semi_in_error_recovery = [&](TokenizedBuffer::Token semi) {
|
||||
return AddLeafNode(ParseNodeKind::DeclarationEnd(), semi);
|
||||
@@ -519,9 +521,9 @@ auto ParseTree::Parser::ParseVariableDeclaration() -> Node {
|
||||
TokenizedBuffer::Token var_token = Consume(TokenKind::Var());
|
||||
auto start = GetSubtreeStartPosition();
|
||||
|
||||
RETURN_IF_STACK_LIMITED(AddNode(ParseNodeKind::VariableDeclaration(),
|
||||
var_token, start,
|
||||
/*has_error=*/true));
|
||||
CARBON_RETURN_IF_STACK_LIMITED(AddNode(ParseNodeKind::VariableDeclaration(),
|
||||
var_token, start,
|
||||
/*has_error=*/true));
|
||||
|
||||
auto pattern = ParsePattern(PatternKind::Variable);
|
||||
if (!pattern) {
|
||||
@@ -557,7 +559,7 @@ auto ParseTree::Parser::ParseEmptyDeclaration() -> Node {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseDeclaration() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
switch (NextTokenKind()) {
|
||||
case TokenKind::Fn():
|
||||
return ParseFunctionDeclaration();
|
||||
@@ -592,7 +594,7 @@ auto ParseTree::Parser::ParseDeclaration() -> llvm::Optional<Node> {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseParenExpression() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
// parenthesized-expression ::= `(` expression `)`
|
||||
// tuple-literal ::= `(` `)`
|
||||
// ::= `(` expression `,` [expression-list [`,`]] `)`
|
||||
@@ -615,7 +617,7 @@ auto ParseTree::Parser::ParseParenExpression() -> llvm::Optional<Node> {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseBraceExpression() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
// braced-expression ::= `{` [field-value-list] `}`
|
||||
// ::= `{` field-type-list `}`
|
||||
// field-value-list ::= field-value [`,`]
|
||||
@@ -695,7 +697,7 @@ auto ParseTree::Parser::ParseBraceExpression() -> llvm::Optional<Node> {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParsePrimaryExpression() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
llvm::Optional<ParseNodeKind> kind;
|
||||
switch (NextTokenKind()) {
|
||||
case TokenKind::Identifier():
|
||||
@@ -756,7 +758,7 @@ auto ParseTree::Parser::ParseDesignatorExpression(SubtreeStart start,
|
||||
|
||||
auto ParseTree::Parser::ParseCallExpression(SubtreeStart start, bool has_errors)
|
||||
-> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
// `(` expression-list[opt] `)`
|
||||
//
|
||||
// expression-list ::= expression
|
||||
@@ -772,7 +774,7 @@ auto ParseTree::Parser::ParseCallExpression(SubtreeStart start, bool has_errors)
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParsePostfixExpression() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
auto start = GetSubtreeStartPosition();
|
||||
llvm::Optional<Node> expression = ParsePrimaryExpression();
|
||||
|
||||
@@ -794,7 +796,7 @@ auto ParseTree::Parser::ParsePostfixExpression() -> llvm::Optional<Node> {
|
||||
// This is subject to an infinite loop if a child call fails, so monitor for
|
||||
// stalling.
|
||||
if (last_position == position_) {
|
||||
CHECK(expression == llvm::None);
|
||||
CARBON_CHECK(expression == llvm::None);
|
||||
return expression;
|
||||
}
|
||||
last_position = position_;
|
||||
@@ -828,7 +830,7 @@ static auto IsPossibleStartOfOperand(TokenKind kind) -> bool {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::IsLexicallyValidInfixOperator() -> bool {
|
||||
CHECK(!AtEndOfFile()) << "Expected an operator token.";
|
||||
CARBON_CHECK(!AtEndOfFile()) << "Expected an operator token.";
|
||||
|
||||
bool leading_space = tokens_.HasLeadingWhitespace(*position_);
|
||||
bool trailing_space = tokens_.HasTrailingWhitespace(*position_);
|
||||
@@ -929,7 +931,7 @@ auto ParseTree::Parser::ParseOperatorExpression(
|
||||
OperatorRequiresParentheses, Error,
|
||||
"Parentheses are required to disambiguate operator precedence.");
|
||||
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
auto start = GetSubtreeStartPosition();
|
||||
|
||||
llvm::Optional<Node> lhs;
|
||||
@@ -1002,17 +1004,17 @@ auto ParseTree::Parser::ParseOperatorExpression(
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseExpression() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
return ParseOperatorExpression(PrecedenceGroup::ForTopLevelExpression());
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseType() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
return ParseOperatorExpression(PrecedenceGroup::ForType());
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseExpressionStatement() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
TokenizedBuffer::Token start_token = *position_;
|
||||
auto start = GetSubtreeStartPosition();
|
||||
|
||||
@@ -1041,7 +1043,7 @@ auto ParseTree::Parser::ParseExpressionStatement() -> llvm::Optional<Node> {
|
||||
|
||||
auto ParseTree::Parser::ParseParenCondition(TokenKind introducer)
|
||||
-> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
// `(` expression `)`
|
||||
auto start = GetSubtreeStartPosition();
|
||||
auto open_paren = ConsumeIf(TokenKind::OpenParen());
|
||||
@@ -1085,7 +1087,7 @@ auto ParseTree::Parser::ParseIfStatement() -> llvm::Optional<Node> {
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseWhileStatement() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
auto start = GetSubtreeStartPosition();
|
||||
auto while_token = Consume(TokenKind::While());
|
||||
auto cond = ParseParenCondition(TokenKind::While());
|
||||
@@ -1097,9 +1099,9 @@ auto ParseTree::Parser::ParseWhileStatement() -> llvm::Optional<Node> {
|
||||
auto ParseTree::Parser::ParseKeywordStatement(ParseNodeKind kind,
|
||||
KeywordStatementArgument argument)
|
||||
-> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
auto keyword_kind = NextTokenKind();
|
||||
CHECK(keyword_kind.IsKeyword());
|
||||
CARBON_CHECK(keyword_kind.IsKeyword());
|
||||
|
||||
auto start = GetSubtreeStartPosition();
|
||||
auto keyword = Consume(keyword_kind);
|
||||
@@ -1123,7 +1125,7 @@ auto ParseTree::Parser::ParseKeywordStatement(ParseNodeKind kind,
|
||||
}
|
||||
|
||||
auto ParseTree::Parser::ParseStatement() -> llvm::Optional<Node> {
|
||||
RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
CARBON_RETURN_IF_STACK_LIMITED(llvm::None);
|
||||
switch (NextTokenKind()) {
|
||||
case TokenKind::Var():
|
||||
return ParseVariableDeclaration();
|
||||
|
||||
@@ -122,7 +122,7 @@ struct OperatorPriorityTable {
|
||||
for (int8_t a = 0; a != NumPrecedenceLevels; ++a) {
|
||||
for (int8_t b = 0; b != NumPrecedenceLevels; ++b) {
|
||||
if (table[a][b] == OperatorPriority::LeftFirst) {
|
||||
CHECK(table[b][a] != OperatorPriority::LeftFirst)
|
||||
CARBON_CHECK(table[b][a] != OperatorPriority::LeftFirst)
|
||||
<< "inconsistent lookup table entries";
|
||||
table[b][a] = OperatorPriority::RightFirst;
|
||||
}
|
||||
@@ -165,13 +165,13 @@ struct OperatorPriorityTable {
|
||||
constexpr void ConsistencyCheck() {
|
||||
for (int8_t level = 0; level != NumPrecedenceLevels; ++level) {
|
||||
if (level != Highest) {
|
||||
CHECK(table[Highest][level] == OperatorPriority::LeftFirst &&
|
||||
table[level][Highest] == OperatorPriority::RightFirst)
|
||||
CARBON_CHECK(table[Highest][level] == OperatorPriority::LeftFirst &&
|
||||
table[level][Highest] == OperatorPriority::RightFirst)
|
||||
<< "Highest is not highest priority";
|
||||
}
|
||||
if (level != Lowest) {
|
||||
CHECK(table[Lowest][level] == OperatorPriority::RightFirst &&
|
||||
table[level][Lowest] == OperatorPriority::LeftFirst)
|
||||
CARBON_CHECK(table[Lowest][level] == OperatorPriority::RightFirst &&
|
||||
table[level][Lowest] == OperatorPriority::LeftFirst)
|
||||
<< "Lowest is not lowest priority";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ void SemanticsIRFactory::ProcessRoots() {
|
||||
// No action needed.
|
||||
break;
|
||||
default:
|
||||
FATAL() << "Unhandled node kind: "
|
||||
<< semantics_.parse_tree_->node_kind(node).name();
|
||||
CARBON_FATAL() << "Unhandled node kind: "
|
||||
<< semantics_.parse_tree_->node_kind(node).name();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,8 +49,8 @@ void SemanticsIRFactory::ProcessFunctionNode(SemanticsIR::Block& block,
|
||||
// TODO: Should accumulate the definition into the code block.
|
||||
break;
|
||||
default:
|
||||
FATAL() << "Unhandled node kind: "
|
||||
<< semantics_.parse_tree_->node_kind(node).name();
|
||||
CARBON_FATAL() << "Unhandled node kind: "
|
||||
<< semantics_.parse_tree_->node_kind(node).name();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ SourceBuffer::SourceBuffer(std::string filename, llvm::StringRef text)
|
||||
: content_mode_(ContentMode::MMapped),
|
||||
filename_(std::move(filename)),
|
||||
text_(text) {
|
||||
CHECK(!text.empty())
|
||||
CARBON_CHECK(!text.empty())
|
||||
<< "Must not have an empty text when we have mapped data from a file!";
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ SourceBuffer::~SourceBuffer() {
|
||||
int result =
|
||||
munmap(const_cast<void*>(static_cast<const void*>(text_.data())),
|
||||
text_.size());
|
||||
CHECK(result != -1) << "Unmapping text failed!";
|
||||
CARBON_CHECK(result != -1) << "Unmapping text failed!";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user