From 0619b4ce6a619e0be3a7d34c2186496d906099b3 Mon Sep 17 00:00:00 2001 From: Jon Meow <46229924+jonmeow@users.noreply.github.com> Date: Thu, 19 Aug 2021 12:31:25 -0700 Subject: [PATCH] Provide a BisonWrap for default construction (#761) Co-authored-by: Geoff Romer --- executable_semantics/syntax/BUILD | 7 ++++ executable_semantics/syntax/bison_wrap.h | 41 ++++++++++++++++++++++++ executable_semantics/syntax/parser.ypp | 13 ++++---- 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 executable_semantics/syntax/bison_wrap.h diff --git a/executable_semantics/syntax/BUILD b/executable_semantics/syntax/BUILD index 6a69c5b8f8fa..6a363e79f687 100644 --- a/executable_semantics/syntax/BUILD +++ b/executable_semantics/syntax/BUILD @@ -6,6 +6,12 @@ load("@rules_cc//cc:defs.bzl", "cc_library") package(default_visibility = ["//executable_semantics:__pkg__"]) +cc_library( + name = "bison_wrap", + hdrs = ["bison_wrap.h"], + deps = ["//common:check"], +) + cc_library( name = "syntax", srcs = [ @@ -28,6 +34,7 @@ cc_library( "-Wno-writable-strings", ], deps = [ + ":bison_wrap", "//common:check", "//common:ostream", "//common:string_helpers", diff --git a/executable_semantics/syntax/bison_wrap.h b/executable_semantics/syntax/bison_wrap.h new file mode 100644 index 000000000000..b9dc175aff0c --- /dev/null +++ b/executable_semantics/syntax/bison_wrap.h @@ -0,0 +1,41 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_ +#define EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_ + +#include + +#include "common/check.h" + +namespace Carbon { + +// Bison requires that types be default initializable for use with its variant +// semantics. This wraps arbitrary types to support a default constructor, while +// still requiring they be properly initialized. +template +class BisonWrap { + public: + // Assigning a value initializes the wrapper. + BisonWrap& operator=(T&& rhs) { + val = std::move(rhs); + return *this; + } + + // Support transparent conversion to the wrapped type, erroring if not + // initialized. + operator T() { + CHECK(val.has_value()); + T ret = std::move(*val); + val.reset(); + return ret; + } + + private: + std::optional val; +}; + +} // namespace Carbon + +#endif // EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_ diff --git a/executable_semantics/syntax/parser.ypp b/executable_semantics/syntax/parser.ypp index f5056ba6da21..95560e5a3330 100644 --- a/executable_semantics/syntax/parser.ypp +++ b/executable_semantics/syntax/parser.ypp @@ -71,6 +71,7 @@ #include "executable_semantics/common/arena.h" #include "executable_semantics/common/ptr.h" #include "executable_semantics/ast/paren_contents.h" +#include "executable_semantics/syntax/bison_wrap.h" namespace Carbon { class ParseAndLexContext; @@ -93,7 +94,7 @@ void Carbon::Parser::error(const location_type&, const std::string& message) { %token sized_type_literal %token string_literal %type designator -%type declaration +%type >> declaration %type function_declaration %type function_definition %type >> declaration_list @@ -567,20 +568,20 @@ alternative_list: ; declaration: function_definition - { $$ = global_arena->RawNew($1); } + { $$ = global_arena->New($1); } | function_declaration - { $$ = global_arena->RawNew($1); } + { $$ = global_arena->New($1); } | CLASS identifier "{" member_list "}" { - $$ = global_arena->RawNew(yylineno, $2, $4); + $$ = global_arena->New(yylineno, $2, $4); } | CHOICE identifier "{" alternative_list "}" { - $$ = global_arena->RawNew(yylineno, $2, $4); + $$ = global_arena->New(yylineno, $2, $4); } | VAR variable_declaration "=" expression ";" { - $$ = global_arena->RawNew(yylineno, $2, $4); + $$ = global_arena->New(yylineno, $2, $4); } ; declaration_list: