diff --git a/docs/AST_Types.md b/docs/AST_Types.md index acc8390..40286bf 100644 --- a/docs/AST_Types.md +++ b/docs/AST_Types.md @@ -72,12 +72,13 @@ Stores a comment. Fields: ```cpp -StringCached Content; -Code Prev; -Code Next; -Code Parent; -StringCached Name; -CodeT Type; +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; ``` Serialization: @@ -102,6 +103,7 @@ CodeType ParentType; CodeBody Body; CodeType Prev; // Used to store references to interfaces CodeType Next; // Used to store references to interfaces +parser::Token* Tok; Code Parent; StringCached Name; CodeT Type; diff --git a/docs/Parser_Algo.md b/docs/Parser_Algo.md index 18af8d7..7b9bd2f 100644 --- a/docs/Parser_Algo.md +++ b/docs/Parser_Algo.md @@ -106,7 +106,7 @@ internal } ``` -Below is an outline of the general alogirithim used for these internal procedures. The intention is provide a basic briefing to aid the user in traversing the actual code definitions. These appear in the same order as they are in the `parser.cpp` file +Below is an outline of the general alogirithim used for these internal procedures. The intention is to provide a basic briefing to aid the user in traversing the actual code definitions. These appear in the same order as they are in the `parser.cpp` file ## `parse_array_decl` @@ -127,30 +127,155 @@ Below is an outline of the general alogirithim used for these internal procedure ## `parse_class_struct` - +1. Check for export module specifier +2. class or struct keyword +3. `parse_attributes` +4. If identifier : `parse_identifier` +5. Parse inherited parent or interfaces +6. If opening curly brace : `parse_class_struct_body` +7. If not an inplace definition + 1. End statement + 2. Check for inline comment ## `parse_class_struct_body` +1. Opening curly brace +2. Parse the body (Possible options): + 1. Newline : ast constant + 2. Comment : `parse_comment` + 3. Access_Public : ast constant + 4. Access_Protected : ast constant + 5. Access_Private : ast constant + 6. Decl_Class : `parse_complicated_definition` + 7. Decl_Enum : `parse_complicated_definition` + 8. Decl_Friend : `parse_friend` + 9. Decl_Operator : `parse_operator_cast` + 10. Decl_Struct : `parse_complicated_definition` + 11. Decl_Template : `parse_template` + 12. Decl_Typedef : `parse_typedef` + 13. Decl_Union : `parse_complicated_definition` + 14. Decl_Using : `parse_using` + 15. Operator == '~' + 1. `parse_destructor` + 16. Preprocess_Define : `parse_define` + 17. Preprocess_Include : `parse_include` + 18. Preprocess_Conditional (if, ifdef, ifndef, elif, else, endif) : `parse_preprocess_cond` or else/endif ast constant + 19. Preprocess_Macro : `parse_simple_preprocess` + 20. Preprocess_Pragma : `parse_pragma` + 21. Preprocess_Unsupported : `parse_simple_preprocess` + 22. StaticAssert : `parse_static_assert` + 23. The following compound into a resolved definition or declaration: + 1. Attributes (Standard, GNU, MSVC) : `parse_attributes` + 2. Specifiers (consteval, constexpr, constinit, forceinline, inline, mutable, neverinline, static, volatile) + 3. Possible Destructor : `parse_destructor` + 4. Possible User defined operator cast : `parse_operator_cast` + 5. Possible Constructor : `parse_constructor` + 6. Something that has the following: (identifier, const, unsigned, signed, short, long, bool, char, int, double) + 1. Possible Constructor `parse_constructor` + 2. Possible Operator, Function, or varaible : `parse_operator_function_or_variable` + 24. Something completely unknown (will just make untyped...) : `parse_untyped` + ## `parse_comment` +1. Just wrap the token into a cached string ( the lexer did the processing ) + ## `parse_compilcated_definition` +This is a helper function used by the following functions to help resolve a declaration or definition: + +* `parse_class_struct_body` +* `parse_global_nspace` +* `parse_union` + +A portion of the code in `parse_typedef` is very similar to this as both have to resolve a similar issue. + +1. Look ahead to the termination token (End statement) +2. Check to see if it fits the pattern for a forward declare +3. If the previous token was an identifier ( `token[-1]` ): + 1. Look back one more token : `[-2]` + 2. If the token has a closing brace its an inplace definition + 3. If the `token[-2]` is an identifier & `token[-3]` is the declaration type, its a variable using a namespaced type. + 4. If the `token[-2]` is an indirection, then its a variable using a namespaced/forwarded type. + 5. If any of the above is the case, `parse_operator_function_or_variable` +4. If the previous token was a closing curly brace, its a definition : `parse_forward_or_definition` +5. If the previous token was a closing square brace, its an array definition : `parse_operator_function_or_variable` + ## `parse_define` +1. Define directive +2. Get identifier +3. Get Content + ## `parse_forward_or_definition` +* Parse any of the following for either a forward declaration or definition: + 1. Decl_Class : `parse_class` + 2. Decl_Enum : `parse_enum` + 3. Decl_Struct : `parse_struct` + 4. Decl_Union : `parse_union` + ## `parse_function_after_name` +This is needed as a function defintion is not easily resolvable early on, as such this function handles resolving a function +after its been made ceratin that the type of declaration or definition is indeed for a function signature. + +By the point this function is called the following are known : export module flag, attributes, specifiers, return type, & name + +1. `parse_parameters` +2. parse postfix specifiers (we do not check if the specifier here is correct or not to be here... yet) +3. If there is a body : `parse_body` +4. Otherwise : + 1. Statment end + 2. Check for inline comment + ## `parse_function_body` +Currently there is no actual parsing of the function body. Any content with the braces is shoved into an execution AST node. +In the future statements and expressions will be parsed. + +1. Open curly brace +2. Grab all tokens between the brace and the closing brace, shove them in a execution AST node. +3. Closing curly brace + ## `parse_global_nspace` -1. Make sure the type provided to the helper function is a `Namespace_Body`, `Global_Body`, `Export_Body`, `Extern_Linkage_body`. -2. If its not a `Global_Body` eat the opening brace for the scope. -3. ` +1. Make sure this is being called for a valid type (namespace, global body, export body, linkage body) +2. If its not a global body, consume the opening curly brace +3. Parse the body (Possible options): + 1. NewLine : ast constant + 2. Comment : `parse_comment` + 3. Decl_Cass : `parse_complicated_definition` + 4. Decl_Enum : `parse_complicated_definition` + 5. Decl_Extern_Linkage : `parse_extern_link` + 6. Decl_Namespace : `parse_namespace` + 7. Decl_Struct : `parse_complicated_definition` + 8. Decl_Template : `parse_template` + 9. Decl_Typedef : `parse_typedef` + 10. Decl_Union : `parse_complicated_definition` + 11. Decl_Using : `parse_using` + 12. Preprocess_Define : `parse_define` + 13. Preprocess_Include : `parse_include` + 14. Preprocess_If, IfDef, IfNotDef, Elif : `parse_preprocess_cond` + 15. Preprocess_Else : ast constant + 16. Preprocess_Endif : ast constant + 17. Preprocess_Macro : `parse_simple_preprocess` + 18. Preprocess_Pragma : `parse_pragma` + 19. Preprocess_Unsupported : `parse_simple_preprocess` + 20. StaticAssert : `parse_static_assert` + 21. Module_Export : `parse_export_body` + 22. Module_Import : NOT_IMPLEMENTED + 23. The following compound into a resolved definition or declaration: + 1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes` + 2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static ) + 3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int) + 1. If its an operator cast (definition outside class) : `parse_operator_cast` + 2. Its an operator, function, or varaible : `parse_operator_function_or_varaible` +4. If its not a global body, consuem the closing curly brace ## `parse_identifier` + + ## `parse_include` ## `parse_operator_after_ret_type` @@ -224,7 +349,7 @@ Below is an outline of the general alogirithim used for these internal procedure 5. Decl_Struct 6. Decl_Union 7. Preprocess_Define - 8. Preprocess_Conditional + 8. Preprocess_Conditional (if, ifdef, ifndef, elif, else, endif) 9. Preprocess_Macro 10. Preprocess_Pragma 11. Unsupported preprocess directive diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 8d8433f..88729f1 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -11,6 +11,7 @@ struct AST_Body; struct AST_Attributes; struct AST_Comment; struct AST_Constructor; +// struct AST_BaseClass; struct AST_Class; struct AST_Define; struct AST_Destructor; @@ -76,6 +77,7 @@ struct Code; struct CodeBody; // These are to offer ease of use and optionally strong type safety for the AST. struct CodeAttributes; +// struct CodeBaseClass; struct CodeComment; struct CodeClass; struct CodeConstructor; @@ -203,12 +205,14 @@ struct Code #ifdef GEN_ENFORCE_STRONG_CODE_TYPES # define operator explicit operator #endif + operator CodeBody() const; operator CodeAttributes() const; + // operator CodeBaseClass() const; operator CodeComment() const; - operator CodeConstructor() const; - operator CodeDestructor() const; operator CodeClass() const; + operator CodeConstructor() const; operator CodeDefine() const; + operator CodeDestructor() const; operator CodeExec() const; operator CodeEnum() const; operator CodeExtern() const; @@ -230,7 +234,6 @@ struct Code operator CodeUnion() const; operator CodeUsing() const; operator CodeVar() const; - operator CodeBody() const; #undef operator }; @@ -273,6 +276,7 @@ struct AST operator Code(); operator CodeBody(); operator CodeAttributes(); + // operator CodeBaseClass(); operator CodeComment(); operator CodeConstructor(); operator CodeDestructor(); diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 58418ce..1213325 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -15,7 +15,7 @@ struct AST_Body char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Front; Code Back; - parser::Token* Token; + parser::Token* Tok; Code Parent; StringCached Name; CodeT Type; @@ -32,7 +32,7 @@ struct AST_Attributes }; Code Prev; Code Next; - parser::Token* Token; + parser::Token* Tok; Code Parent; StringCached Name; CodeT Type; @@ -40,6 +40,23 @@ struct AST_Attributes }; static_assert( sizeof(AST_Attributes) == sizeof(AST), "ERROR: AST_Attributes is not the same size as AST"); +#if 0 +struct AST_BaseClass +{ + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; + }; + Code Prev; + Code Next; + parser::Token* Tok; + Code Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; +}; +static_assert( sizeof(AST_BaseClass) == sizeof(AST), "ERROR: AST_BaseClass is not the same size as AST"); +#endif + struct AST_Comment { union { @@ -48,7 +65,7 @@ struct AST_Comment }; Code Prev; Code Next; - parser::Token* Token; + parser::Token* Tok; Code Parent; StringCached Name; CodeT Type; diff --git a/project/components/code_types.hpp b/project/components/code_types.hpp index 6ceba67..64cfe6d 100644 --- a/project/components/code_types.hpp +++ b/project/components/code_types.hpp @@ -240,6 +240,7 @@ struct CodeStruct } Define_CodeType( Attributes ); +// Define_CodeType( BaseClass ); Define_CodeType( Comment ); struct CodeConstructor diff --git a/project/components/parser.cpp b/project/components/parser.cpp index f2b4c17..09ebf3a 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -668,45 +668,54 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) mflags = ModuleFlag::Export; eat( TokType::Module_Export ); } + // eat( which ); + // attributes = parse_attributes(); + // if ( check( TokType::Identifier ) ) { name = parse_identifier(); Context.Scope->Name = name; } + // local_persist char interface_arr_mem[ kilobytes(4) ] {0}; Array interfaces = Array::init_reserve( Arena::init_from_memory(interface_arr_mem, kilobytes(4) ), 4 ); + // TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them. if ( check( TokType::Assign_Classifer ) ) { eat( TokType::Assign_Classifer ); + // : if ( currtok.is_access_specifier() ) { access = currtok.to_access_specifier(); + // : } Token parent_tok = parse_identifier(); parent = def_type( parent_tok ); + // : while ( check(TokType::Comma) ) { - eat(TokType::Access_Public); + eat( TokType::Comma ); + // : , if ( currtok.is_access_specifier() ) { eat(currtok.Type); } - Token interface_tok = parse_identifier(); interfaces.append( def_type( interface_tok ) ); + // : , ... } } @@ -714,15 +723,18 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) { body = parse_class_struct_body( which, name ); } + // : , ... { } CodeComment inline_cmt = NoCode; if ( ! inplace_def ) { Token stmt_end = currtok; eat( TokType::Statement_End ); + // : , ... { }; if ( currtok_noskip.Type == TokType::Comment && currtok_noskip.Line == stmt_end.Line ) inline_cmt = parse_comment(); + // : , ... { }; } if ( which == TokType::Decl_Class ) @@ -745,6 +757,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) push_scope(); eat( TokType::BraceCurly_Open ); + // { CodeBody result = (CodeBody) make_code(); @@ -783,54 +796,66 @@ CodeBody parse_class_struct_body( TokType which, Token name ) member = access_public; eat( TokType::Access_Public ); eat( TokType::Assign_Classifer ); + // public: break; case TokType::Access_Protected: member = access_protected; eat( TokType::Access_Protected ); eat( TokType::Assign_Classifer ); + // protected: break; case TokType::Access_Private: member = access_private; eat( TokType::Access_Private ); eat( TokType::Assign_Classifer ); + // private: break; case TokType::Decl_Class: member = parse_complicated_definition( TokType::Decl_Class ); + // class break; case TokType::Decl_Enum: member = parse_complicated_definition( TokType::Decl_Enum ); + // enum break; case TokType::Decl_Friend: member = parse_friend(); + // friend break; case TokType::Decl_Operator: member = parse_operator_cast(); + // operator () break; case TokType::Decl_Struct: member = parse_complicated_definition( TokType::Decl_Struct ); + // struct break; case TokType::Decl_Template: member = parse_template(); + // template< ... > break; case TokType::Decl_Typedef: member = parse_typedef(); + // typedef break; case TokType::Decl_Union: member = parse_complicated_definition( TokType::Decl_Union ); + // union break; case TokType::Decl_Using: member = parse_using(); + // using break; case TokType::Operator: @@ -841,14 +866,17 @@ CodeBody parse_class_struct_body( TokType which, Token name ) } member = parse_destructor(); + // ~() break; case TokType::Preprocess_Define: member = parse_define(); + // #define break; case TokType::Preprocess_Include: member = parse_include(); + // #include break; case TokType::Preprocess_If: @@ -856,32 +884,39 @@ CodeBody parse_class_struct_body( TokType which, Token name ) case TokType::Preprocess_IfNotDef: case TokType::Preprocess_ElIf: member = parse_preprocess_cond(); - break; - - case TokType::Preprocess_Macro: - member = parse_simple_preprocess( TokType::Preprocess_Macro ); - break; - - case TokType::Preprocess_Pragma: - member = parse_pragma(); + // # break; case TokType::Preprocess_Else: member = preprocess_else; eat( TokType::Preprocess_Else ); + // #else break; case TokType::Preprocess_EndIf: member = preprocess_endif; eat( TokType::Preprocess_EndIf ); + // #endif + break; + + case TokType::Preprocess_Macro: + member = parse_simple_preprocess( TokType::Preprocess_Macro ); + // + break; + + case TokType::Preprocess_Pragma: + member = parse_pragma(); + // #pragma break; case TokType::Preprocess_Unsupported: member = parse_simple_preprocess( TokType::Preprocess_Unsupported ); + // # break; case TokType::StaticAssert: member = parse_static_assert(); + // static_assert break; case TokType::Attribute_Open: @@ -892,6 +927,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) #undef Entry { attributes = parse_attributes(); + // } //! Fallthrough intended case TokType::Spec_Consteval: @@ -942,16 +978,19 @@ CodeBody parse_class_struct_body( TokType which, Token name ) { specifiers = def_specifiers( NumSpecifiers, specs_found ); } + // if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' ) { member = parse_destructor( specifiers ); + // ~() break; } if ( currtok.Type == TokType::Decl_Operator ) { member = parse_operator_cast( specifiers ); + // operator () break; } } @@ -972,11 +1011,15 @@ CodeBody parse_class_struct_body( TokType which, Token name ) if ( str_compare( name.Text, currtok.Text, name.Length ) == 0 ) { member = parse_constructor(); + // () break; } } member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); + // operator ... + // or + // ... } break; @@ -990,6 +1033,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) } member = untyped_str( untyped_tok ); + // Something unknown break; } @@ -1004,6 +1048,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) } eat( TokType::BraceCurly_Close ); + // { } Context.pop(); return result; } @@ -1053,6 +1098,7 @@ Code parse_complicated_definition( TokType which ) { // Its a forward declaration only Code result = parse_forward_or_definition( which, is_inplace ); + // ; Context.pop(); return result; } @@ -1074,9 +1120,9 @@ Code parse_complicated_definition( TokType which ) ok_to_parse = true; is_inplace = true; } - else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == TokType::Decl_Struct ) + else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == which ) { - // Its a variable with type ID using struct namespace. + // Its a variable with type ID using namespace. // ; ok_to_parse = true; } @@ -1095,22 +1141,23 @@ Code parse_complicated_definition( TokType which ) } Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } ); + // , or Name> ... Context.pop(); return result; } else if ( tok.Type == TokType::BraceCurly_Close ) { // Its a definition - // { ... }; Code result = parse_forward_or_definition( which, is_inplace ); + // { ... }; Context.pop(); return result; } else if ( tok.Type == TokType::BraceSquare_Close) { // Its an array definition - // [ ... ]; Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } ); + // [ ... ]; Context.pop(); return result; } @@ -1127,6 +1174,7 @@ CodeDefine parse_define() { push_scope(); eat( TokType::Preprocess_Define ); + // #define CodeDefine define = (CodeDefine) make_code(); @@ -1142,6 +1190,7 @@ CodeDefine parse_define() Context.Scope->Name = currtok; define->Name = get_cached_string( currtok ); eat( TokType::Identifier ); + // #define if ( ! check( TokType::Preprocess_Content )) { @@ -1154,6 +1203,7 @@ CodeDefine parse_define() { define->Content = get_cached_string( currtok ); eat( TokType::Preprocess_Content ); + // #define Context.pop(); return define; @@ -1161,6 +1211,7 @@ CodeDefine parse_define() define->Content = get_cached_string( strip_formatting( currtok, strip_formatting_dont_preserve_newlines ) ); eat( TokType::Preprocess_Content ); + // #define Context.pop(); return define; @@ -1212,8 +1263,9 @@ CodeFn parse_function_after_name( { push_scope(); CodeParam params = parse_params(); + // ( ) - // These have to be kept separate from the return type's specifiers. + // TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. while ( left && currtok.is_specifier() ) { if ( specifiers.ast == nullptr ) @@ -1226,6 +1278,7 @@ CodeFn parse_function_after_name( specifiers.append( ESpecifier::to_type(currtok) ); eat( currtok.Type ); } + // ( ) CodeBody body = NoCode; CodeComment inline_cmt = NoCode; @@ -1237,14 +1290,17 @@ CodeFn parse_function_after_name( Context.pop(); return CodeInvalid; } + // ( ) { } } else { Token stmt_end = currtok; eat( TokType::Statement_End ); + // ( ) ; if ( currtok_noskip.Type == TokType::Comment && currtok_noskip.Line == stmt_end.Line ) inline_cmt = parse_comment(); + // ( ) ; } using namespace ECode; @@ -1349,6 +1405,7 @@ CodeBody parse_global_nspace( CodeT which ) if ( which != Global_Body ) eat( TokType::BraceCurly_Open ); + // { CodeBody result = (CodeBody) make_code(); @@ -1381,10 +1438,12 @@ CodeBody parse_global_nspace( CodeT which ) case TokType::Decl_Class: member = parse_complicated_definition( TokType::Decl_Class ); + // class break; case TokType::Decl_Enum: member = parse_complicated_definition( TokType::Decl_Enum ); + // enum break; case TokType::Decl_Extern_Linkage: @@ -1392,38 +1451,47 @@ CodeBody parse_global_nspace( CodeT which ) log_failure( "Nested extern linkage\n%s", Context.to_string() ); member = parse_extern_link(); + // extern "..." { ... } break; case TokType::Decl_Namespace: member = parse_namespace(); + // namespace { ... } break; case TokType::Decl_Struct: member = parse_complicated_definition( TokType::Decl_Struct ); + // struct ... break; case TokType::Decl_Template: member = parse_template(); + // template<...> ... break; case TokType::Decl_Typedef: member = parse_typedef(); + // typedef ... break; case TokType::Decl_Union: member = parse_complicated_definition( TokType::Decl_Union ); + // union ... break; case TokType::Decl_Using: member = parse_using(); + // using ... break; case TokType::Preprocess_Define: member = parse_define(); + // #define ... break; case TokType::Preprocess_Include: member = parse_include(); + // #include ... break; case TokType::Preprocess_If: @@ -1431,32 +1499,39 @@ CodeBody parse_global_nspace( CodeT which ) case TokType::Preprocess_IfNotDef: case TokType::Preprocess_ElIf: member = parse_preprocess_cond(); - break; - - case TokType::Preprocess_Macro: - member = parse_simple_preprocess( TokType::Preprocess_Macro ); - break; - - case TokType::Preprocess_Pragma: - member = parse_pragma(); + // # ... break; case TokType::Preprocess_Else: member = preprocess_else; eat( TokType::Preprocess_Else ); + // #else break; case TokType::Preprocess_EndIf: member = preprocess_endif; eat( TokType::Preprocess_EndIf ); + // #endif + break; + + case TokType::Preprocess_Macro: + member = parse_simple_preprocess( TokType::Preprocess_Macro ); + // + break; + + case TokType::Preprocess_Pragma: + member = parse_pragma(); + // #pragma ... break; case TokType::Preprocess_Unsupported: member = parse_simple_preprocess( TokType::Preprocess_Unsupported ); + // # ... break; case TokType::StaticAssert: member = parse_static_assert(); + // static_assert( , ... ); break; case TokType::Module_Export: @@ -1464,13 +1539,16 @@ CodeBody parse_global_nspace( CodeT which ) log_failure( "Nested export declaration\n%s", Context.to_string() ); member = parse_export_body(); + // export { ... } break; case TokType::Module_Import: { not_implemented( context ); + // import ... } //! Fallthrough intentional + case TokType::Attribute_Open: case TokType::Decl_GNU_Attribute: case TokType::Decl_MSVC_Attribute: #define Entry( attribute, str ) case TokType::attribute: @@ -1478,6 +1556,7 @@ CodeBody parse_global_nspace( CodeT which ) #undef Entry { attributes = parse_attributes(); + // } //! Fallthrough intentional case TokType::Spec_Consteval: @@ -1542,6 +1621,7 @@ CodeBody parse_global_nspace( CodeT which ) { specifiers = def_specifiers( NumSpecifiers, specs_found ); } + // } //! Fallthrough intentional case TokType::Identifier: @@ -1581,10 +1661,12 @@ CodeBody parse_global_nspace( CodeT which ) if ( found_operator_cast ) { member = parse_operator_cast(); + // ::operator () { ... } break; } member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); + // ... } } @@ -1600,6 +1682,7 @@ CodeBody parse_global_nspace( CodeT which ) if ( which != Global_Body ) eat( TokType::BraceCurly_Close ); + // { } return result; }