diff --git a/gencpp.10x b/gencpp.10x index da64cf6..a73542d 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -10,7 +10,7 @@ false false pwsh ./scripts/build.ps1 msvc debug bootstrap - + pwsh ./scripts/build.ps1 msvc debug c_library pwsh ./scripts/clean.ps1 diff --git a/project/components/ast.cpp b/project/components/ast.cpp index f101ec4..2cda82a 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -559,7 +559,11 @@ void to_string( Code self, String* result ) break; case CT_Union: - to_string( cast(CodeUnion, self), result ); + to_string_def( cast(CodeUnion, self), result ); + break; + + case CT_Union_Fwd: + to_string_fwd( cast(CodeUnion, self), result ); break; case CT_Using: @@ -778,6 +782,7 @@ bool is_equal( Code self, Code other ) check_member_ast( Attributes ); check_member_ast( UnderlyingType ); check_member_ast( Body ); + check_member_ast( UnderlyingTypeMacro ); return true; } @@ -789,6 +794,7 @@ bool is_equal( Code self, Code other ) check_member_str( Name ); check_member_ast( Attributes ); check_member_ast( UnderlyingType ); + check_member_ast( UnderlyingTypeMacro ); return true; } @@ -1058,6 +1064,13 @@ bool is_equal( Code self, Code other ) return true; } + + case CT_Union_Fwd: + { + check_member_val( ModuleFlags ); + check_member_str( Name ); + check_member_ast( Attributes ); + } case CT_Using: case CT_Using_Namespace: diff --git a/project/components/ast.hpp b/project/components/ast.hpp index bfabbb8..2850ac5 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -155,6 +155,7 @@ Define_Code(Var); GEN_NS_PARSER_BEGIN struct Token; GEN_NS_PARSER_END +typedef struct GEN_NS_PARSER Token Token; #if ! GEN_COMPILER_C template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); } @@ -319,9 +320,10 @@ struct AST Code ValueType; // Parameter, Variable }; union { - Code Macro; // Parameter - Code BitfieldSize; // Variable (Class/Struct Data Member) - Code Params; // Constructor, Function, Operator, Template, Typename + Code Macro; // Parameter + Code BitfieldSize; // Variable (Class/Struct Data Member) + Code Params; // Constructor, Function, Operator, Template, Typename + Code UnderlyingTypeMacro; // Enum }; union { Code ArrExpr; // Typename @@ -363,7 +365,6 @@ struct AST AccessSpec ParentAccess; s32 NumEntries; s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. - b32 EnumUnderlyingMacro; // Used by enums incase the user wants to wrap underlying type specification in a macro }; }; static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" ); diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 7825287..8841408 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -15,7 +15,7 @@ struct AST_Body char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; Code Front; Code Back; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -32,7 +32,7 @@ struct AST_Attributes }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -48,7 +48,7 @@ struct AST_BaseClass }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -65,10 +65,10 @@ struct AST_Comment }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; - CodeType Type; + CodeType Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; }; static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not the same size as AST"); @@ -90,7 +90,7 @@ struct AST_Class }; CodeTypename Prev; CodeTypename Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -116,7 +116,7 @@ struct AST_Constructor }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -132,7 +132,7 @@ struct AST_Define }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -156,7 +156,7 @@ struct AST_Destructor }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -181,12 +181,12 @@ struct AST_Enum }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; ModuleFlag ModuleFlags; - b32 EnumUnderlyingMacro; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; }; static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST"); @@ -198,7 +198,7 @@ struct AST_Exec }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -214,7 +214,7 @@ struct AST_Expr }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -229,7 +229,7 @@ struct AST_Expr_Assign }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -244,7 +244,7 @@ struct AST_Expr_Alignof }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -259,7 +259,7 @@ struct AST_Expr_Binary }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -274,7 +274,7 @@ struct AST_Expr_CStyleCast }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -289,7 +289,7 @@ struct AST_Expr_FunctionalCast }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -304,7 +304,7 @@ struct AST_Expr_CppCast }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -319,7 +319,7 @@ struct AST_Expr_ProcCall }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -334,7 +334,7 @@ struct AST_Expr_Decltype }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -349,7 +349,7 @@ struct AST_Expr_Comma }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -364,7 +364,7 @@ struct AST_Expr_AMS }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -379,7 +379,7 @@ struct AST_Expr_Sizeof }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -394,7 +394,7 @@ struct AST_Expr_Subscript }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -409,7 +409,7 @@ struct AST_Expr_Ternary }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -424,7 +424,7 @@ struct AST_Expr_UnaryPrefix }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -439,7 +439,7 @@ struct AST_Expr_UnaryPostfix }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -454,7 +454,7 @@ struct AST_Expr_Element }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -476,7 +476,7 @@ struct AST_Extern }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -492,7 +492,7 @@ struct AST_Include }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -514,7 +514,7 @@ struct AST_Friend }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -539,7 +539,7 @@ struct AST_Fn }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -553,7 +553,7 @@ struct AST_Module char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -574,7 +574,7 @@ struct AST_NS }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -600,7 +600,7 @@ struct AST_Operator }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -626,7 +626,7 @@ struct AST_OpCast }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -650,7 +650,7 @@ struct AST_Param }; CodeParam Last; CodeParam Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -667,7 +667,7 @@ struct AST_Pragma }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -683,7 +683,7 @@ struct AST_PreprocessCond }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -697,7 +697,7 @@ struct AST_Specifiers CodeSpecifiers NextSpecs; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -714,7 +714,7 @@ struct AST_Stmt }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -729,7 +729,7 @@ struct AST_Stmt_Break }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -744,7 +744,7 @@ struct AST_Stmt_Case }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -759,7 +759,7 @@ struct AST_Stmt_Continue }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -774,7 +774,7 @@ struct AST_Stmt_Decl }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -789,7 +789,7 @@ struct AST_Stmt_Do }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -804,7 +804,7 @@ struct AST_Stmt_Expr }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -819,7 +819,7 @@ struct AST_Stmt_Else }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -834,7 +834,7 @@ struct AST_Stmt_If }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -849,7 +849,7 @@ struct AST_Stmt_For }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -864,7 +864,7 @@ struct AST_Stmt_Goto }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -879,7 +879,7 @@ struct AST_Stmt_Label }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -894,7 +894,7 @@ struct AST_Stmt_Switch }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -909,7 +909,7 @@ struct AST_Stmt_While }; CodeExpr Prev; CodeExpr Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -935,7 +935,7 @@ struct AST_Struct }; CodeTypename Prev; CodeTypename Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -958,7 +958,7 @@ struct AST_Template }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -987,7 +987,7 @@ struct AST_Type }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -1014,7 +1014,7 @@ struct AST_Typename }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -1037,7 +1037,7 @@ struct AST_Typedef }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -1061,7 +1061,7 @@ struct AST_Union }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -1085,7 +1085,7 @@ struct AST_Using }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; @@ -1111,7 +1111,7 @@ struct AST_Var }; Code Prev; Code Next; - parser::Token* Tok; + Token* Tok; Code Parent; StringCached Name; CodeType Type; diff --git a/project/components/code_serialization.cpp b/project/components/code_serialization.cpp index 6521a0c..e07ad5e 100644 --- a/project/components/code_serialization.cpp +++ b/project/components/code_serialization.cpp @@ -9,7 +9,7 @@ String to_string(CodeAttributes attributes) { String to_string(CodeBody body) { - GEN_ASSERT(body.ast != nullptr); + GEN_ASSERT_NOT_NULL(body.ast); String result = string_make_reserve( GlobalAllocator, 128 ); switch ( body.ast->Type ) { @@ -350,6 +350,8 @@ void to_string_fwd(CodeEnum self, String* result ) if ( self->UnderlyingType ) string_append_fmt( result, "enum %SC : %S", self->Name, to_string(self->UnderlyingType) ); + else if (self->UnderlyingTypeMacro) + string_append_fmt( result, "enum %SC : %S", self->Name, to_string(self->UnderlyingTypeMacro) ); else string_append_fmt( result, "enum %SC", self->Name ); @@ -1171,11 +1173,19 @@ void to_string(CodeTypename self, String* result ) String to_string(CodeUnion self) { String result = string_make_reserve( GlobalAllocator, 512 ); - to_string( self, & result ); + switch ( self->Type ) + { + case CT_Union: + to_string_def( self, & result ); + break; + case CT_Union_Fwd: + to_string_fwd( self, & result ); + break; + } return result; } -void to_string(CodeUnion self, String* result ) +void to_string_def(CodeUnion self, String* result ) { if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) string_append_strc( result, txt("export ") ); @@ -1204,6 +1214,25 @@ void to_string(CodeUnion self, String* result ) string_append_strc( result, txt(";\n")); } +void to_string_fwd(CodeUnion self, String* result ) +{ + if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export )) + string_append_strc( result, txt("export ") ); + + string_append_strc( result, txt("union ") ); + + if ( self->Attributes ) + string_append_fmt( result, "%S ", to_string(self->Attributes) ); + + if ( self->Name ) + { + string_append_fmt( result, "%SC", self->Name); + } + + if ( self->Parent.ast == nullptr || ( self->Parent->Type != CT_Typedef && self->Parent->Type != CT_Variable ) ) + string_append_strc( result, txt(";\n")); +} + String to_string(CodeUsing self) { String result = string_make_reserve( GlobalAllocator, 128 ); diff --git a/project/components/code_types.hpp b/project/components/code_types.hpp index 2dc989d..dc2e783 100644 --- a/project/components/code_types.hpp +++ b/project/components/code_types.hpp @@ -110,7 +110,8 @@ String to_string(CodeTypedef self); void to_string(CodeTypedef self, String* result); String to_string(CodeUnion self); -void to_string(CodeUnion self, String* result); +void to_string_def(CodeUnion self, String* result); +void to_string_fwd(CodeUnion self, String* result); String to_string (CodeUsing op_cast ); void to_string (CodeUsing op_cast, String* result ); diff --git a/project/components/gen/ecode.hpp b/project/components/gen/ecode.hpp index 20dda85..5560fa4 100644 --- a/project/components/gen/ecode.hpp +++ b/project/components/gen/ecode.hpp @@ -63,6 +63,7 @@ enum CodeType_Def : u32 CT_Typedef, CT_Typename, CT_Union, + CT_Union_Fwd, CT_Union_Body, CT_Using, CT_Using_Namespace, @@ -130,6 +131,7 @@ inline StrC to_str( CodeType type ) { sizeof( "Typedef" ), "Typedef" }, { sizeof( "Typename" ), "Typename" }, { sizeof( "Union" ), "Union" }, + { sizeof( "Union_Fwd" ), "Union_Fwd" }, { sizeof( "Union_Body" ), "Union_Body" }, { sizeof( "Using" ), "Using" }, { sizeof( "Using_Namespace" ), "Using_Namespace" }, diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 541beba..fcb1422 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -122,7 +122,7 @@ void define_constants() fmt_newline = make_code(); fmt_newline->Type = CT_NewLine; set_global(fmt_newline); - + pragma_once = (CodePragma) make_code(); pragma_once->Type = CT_Preprocess_Pragma; pragma_once->Name = get_cached_string( txt("once") ); @@ -227,7 +227,7 @@ void define_constants() # pragma pop_macro("neverinline") # pragma push_macro("enum_underlying") - + array_append(PreprocessorDefines, txt("enum_underlying(")); # pragma pop_macro("enum_underlying") # undef def_constant_spec diff --git a/project/components/parser.cpp b/project/components/parser.cpp index d4c67a9..ea41ea3 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -215,7 +215,7 @@ internal Code parse_operator_function_or_variable( bool expects_fu internal CodePragma parse_pragma (); internal CodeParam parse_params ( bool use_template_capture = false ); internal CodePreprocessCond parse_preprocess_cond (); -internal Code parse_simple_preprocess ( TokType which ); +internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces = false ); internal Code parse_static_assert (); internal void parse_template_args ( Token& token ); internal CodeVar parse_variable_after_name ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename type, StrC name ); @@ -240,7 +240,8 @@ internal CodeTypedef parse_typedef (); internal CodeUnion parse_union ( bool inplace_def = false ); internal CodeUsing parse_using (); -constexpr bool inplace_def = true; +constexpr bool inplace_def = true; +constexpr bool dont_consume_braces = true; // Internal parsing functions @@ -2933,8 +2934,8 @@ CodePreprocessCond parse_preprocess_cond() return cond; } -internal inline -Code parse_simple_preprocess( TokType which ) +internal +Code parse_simple_preprocess( TokType which, bool dont_consume_braces ) { // TODO(Ed): We can handle a macro a bit better than this. It's AST can be made more robust.. // Make an AST_Macro, it should have an Name be the macro itself, with the function body being an optional function body node. @@ -2945,7 +2946,7 @@ Code parse_simple_preprocess( TokType which ) eat( which ); // - if ( peektok.Type == Tok_BraceCurly_Open ) + if ( ! dont_consume_braces && peektok.Type == Tok_BraceCurly_Open ) { // Eat the block scope right after the macro. Were assuming the macro defines a function definition's signature eat( Tok_BraceCurly_Open ); @@ -2985,7 +2986,11 @@ Code parse_simple_preprocess( TokType which ) } else { - if ( str_compare_len( Context.Scope->Prev->ProcName.Ptr, "parse_typedef", Context.Scope->Prev->ProcName.Len ) != 0 ) + if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_enum"))) + { + // Do nothing + } + else if (strc_contains(Context.Scope->Prev->ProcName, txt("parse_typedef"))) { if ( peektok.Type == Tok_Statement_End ) { @@ -3614,15 +3619,14 @@ CodeEnum parse_enum( bool inplace_def ) } // enum : } - else if ( currtok.Type == Tok_Preprocess_Define ) + else if ( currtok.Type == Tok_Preprocess_Macro ) { // We'll support the enum_underlying macro - StrC sig = txt("enum_underlying"); - - if (currtok.Length >= sig.Len && str_compare_len(currtok.Text, sig.Ptr, sig.Len) == 0 ) + StrC sig = txt("enum_underlying("); + if ( strc_contains(to_str(currtok), sig) ) { use_macro_underlying = true; - underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro); + underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, dont_consume_braces ); } } @@ -3793,14 +3797,8 @@ CodeEnum parse_enum( bool inplace_def ) if ( attributes ) result->Attributes = attributes; - if ( type ) - { - result->EnumUnderlyingMacro = use_macro_underlying; - if ( use_macro_underlying ) - result->UnderlyingTypeMacro = underlying_macro; - else - result->UnderlyingType = type; - } + result->UnderlyingTypeMacro = underlying_macro; + result->UnderlyingType = type; if ( inline_cmt ) result->InlineCmt = inline_cmt; @@ -5164,95 +5162,98 @@ CodeUnion parse_union( bool inplace_def ) eat( Tok_Identifier ); } // union - + CodeBody body = { nullptr }; - - eat( Tok_BraceCurly_Open ); - // union { - - body = make_code(); - body->Type = CT_Union_Body; - - while ( ! check_noskip( Tok_BraceCurly_Close ) ) + + if ( ! inplace_def || ! check(Tok_Identifier) ) { - if ( currtok_noskip.Type == Tok_Preprocess_Hash ) - eat( Tok_Preprocess_Hash ); + eat( Tok_BraceCurly_Open ); + // union { - Code member = { nullptr }; - switch ( currtok_noskip.Type ) + body = make_code(); + body->Type = CT_Union_Body; + + while ( ! check_noskip( Tok_BraceCurly_Close ) ) { - case Tok_NewLine: - member = fmt_newline; - eat( Tok_NewLine ); - break; + if ( currtok_noskip.Type == Tok_Preprocess_Hash ) + eat( Tok_Preprocess_Hash ); - case Tok_Comment: - member = parse_comment(); - break; + Code member = { nullptr }; + switch ( currtok_noskip.Type ) + { + case Tok_NewLine: + member = fmt_newline; + eat( Tok_NewLine ); + break; - // TODO(Ed) : Unions can have constructors and destructors + case Tok_Comment: + member = parse_comment(); + break; - case Tok_Decl_Class: - member = parse_complicated_definition( Tok_Decl_Class ); - break; + // TODO(Ed) : Unions can have constructors and destructors - case Tok_Decl_Enum: - member = parse_complicated_definition( Tok_Decl_Enum ); - break; + case Tok_Decl_Class: + member = parse_complicated_definition( Tok_Decl_Class ); + break; - case Tok_Decl_Struct: - member = parse_complicated_definition( Tok_Decl_Struct ); - break; + case Tok_Decl_Enum: + member = parse_complicated_definition( Tok_Decl_Enum ); + break; - case Tok_Decl_Union: - member = parse_complicated_definition( Tok_Decl_Union ); - break; + case Tok_Decl_Struct: + member = parse_complicated_definition( Tok_Decl_Struct ); + break; - case Tok_Preprocess_Define: - member = parse_define(); - break; + case Tok_Decl_Union: + member = parse_complicated_definition( Tok_Decl_Union ); + break; - case Tok_Preprocess_If: - case Tok_Preprocess_IfDef: - case Tok_Preprocess_IfNotDef: - case Tok_Preprocess_ElIf: - member = parse_preprocess_cond(); - break; + case Tok_Preprocess_Define: + member = parse_define(); + break; - case Tok_Preprocess_Else: - member = preprocess_else; - eat( Tok_Preprocess_Else ); - break; + case Tok_Preprocess_If: + case Tok_Preprocess_IfDef: + case Tok_Preprocess_IfNotDef: + case Tok_Preprocess_ElIf: + member = parse_preprocess_cond(); + break; - case Tok_Preprocess_EndIf: - member = preprocess_endif; - eat( Tok_Preprocess_EndIf ); - break; + case Tok_Preprocess_Else: + member = preprocess_else; + eat( Tok_Preprocess_Else ); + break; - case Tok_Preprocess_Macro: - member = parse_simple_preprocess( Tok_Preprocess_Macro ); - break; + case Tok_Preprocess_EndIf: + member = preprocess_endif; + eat( Tok_Preprocess_EndIf ); + break; - case Tok_Preprocess_Pragma: - member = parse_pragma(); - break; + case Tok_Preprocess_Macro: + member = parse_simple_preprocess( Tok_Preprocess_Macro ); + break; - case Tok_Preprocess_Unsupported: - member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); - break; + case Tok_Preprocess_Pragma: + member = parse_pragma(); + break; - default: - member = parse_variable(); - break; + case Tok_Preprocess_Unsupported: + member = parse_simple_preprocess( Tok_Preprocess_Unsupported ); + break; + + default: + member = parse_variable(); + break; + } + + if ( member ) + append(body, member ); } - - if ( member ) - append(body, member ); + // union { + + eat( Tok_BraceCurly_Close ); + // union { } } - // union { - - eat( Tok_BraceCurly_Close ); - // union { } if ( ! inplace_def ) eat( Tok_Statement_End ); @@ -5260,17 +5261,14 @@ CodeUnion parse_union( bool inplace_def ) CodeUnion result = (CodeUnion) make_code(); - result->Type = CT_Union; + result->Type = body ? CT_Union : CT_Union_Fwd; result->ModuleFlags = mflags; if ( name ) result->Name = get_cached_string( name ); - if ( body ) - result->Body = body; - - if ( attributes ) - result->Attributes = attributes; + result->Body = body; + result->Attributes = attributes; pop(& Context); return result; diff --git a/project/enums/ECode.csv b/project/enums/ECode.csv index fb2546c..8ad029e 100644 --- a/project/enums/ECode.csv +++ b/project/enums/ECode.csv @@ -54,6 +54,7 @@ Template Typedef Typename Union +Union_Fwd Union_Body Using Using_Namespace