diff options
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r-- | src/shared/cplusplus/Parser.cpp | 1404 |
1 files changed, 783 insertions, 621 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 670ba02fed..7cb2c8ae86 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -53,13 +53,13 @@ #include "AST.h" #include "Literals.h" #include "ObjectiveCTypeQualifiers.h" -#include <cstdlib> -#include <cstring> -#include <iostream> -#include <cassert> -#include <string> +#include <cstdio> // for putchar +#ifdef ICHECK_BUILD +# include <QString> +#endif #define CPLUSPLUS_NO_DEBUG_RULE +#define MAX_EXPRESSION_DEPTH 100 using namespace CPlusPlus; @@ -72,7 +72,13 @@ class DebugRule { public: DebugRule(const char *name) : name(name) - { std::cout << std::string(depth++, ' ') << name << std::endl; } + { + for (int i = 0; i < depth; ++i) + putchar(' '); + + ++depth; + printf("%s\n", name); + } ~DebugRule() { --depth; } @@ -80,6 +86,68 @@ public: int DebugRule::depth = 0; +inline int precedence(int tokenKind, bool templateArguments) +{ + if (templateArguments && tokenKind == T_GREATER) + return -1; + + switch (tokenKind) { + case T_PIPE_PIPE: return 0; + case T_AMPER_AMPER: return 1; + case T_PIPE: return 2; + case T_CARET: return 3; + case T_AMPER: return 4; + case T_EQUAL_EQUAL: + case T_EXCLAIM_EQUAL: return 5; + case T_GREATER: + case T_LESS: + case T_LESS_EQUAL: + case T_GREATER_EQUAL: return 6; + case T_LESS_LESS: + case T_GREATER_GREATER: return 7; + case T_PLUS: + case T_MINUS: return 8; + case T_STAR: + case T_SLASH: + case T_PERCENT: return 9; + case T_ARROW_STAR: + case T_DOT_STAR: return 10; + + default: + return -1; + } +} + +inline bool isBinaryOperator(int tokenKind) +{ + switch (tokenKind) { + case T_PIPE_PIPE: + case T_AMPER_AMPER: + case T_PIPE: + case T_CARET: + case T_AMPER: + case T_EQUAL_EQUAL: + case T_EXCLAIM_EQUAL: + case T_GREATER: + case T_LESS: + case T_LESS_EQUAL: + case T_GREATER_EQUAL: + case T_LESS_LESS: + case T_GREATER_GREATER: + case T_PLUS: + case T_MINUS: + case T_STAR: + case T_SLASH: + case T_PERCENT: + case T_ARROW_STAR: + case T_DOT_STAR: + return true; + + default: + return false; + } +} + } // end of anonymous namespace #ifndef CPLUSPLUS_NO_DEBUG_RULE @@ -88,6 +156,14 @@ int DebugRule::depth = 0; # define DEBUG_THIS_RULE() do {} while (0) #endif +#define PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, minPrecedence) { \ + if (!parseCastExpression(node)) \ + return false; \ + \ + parseExpressionWithOperatorPrecedence(node, minPrecedence); \ + return true; \ +} + class Parser::Rewind { Parser *_parser; @@ -121,7 +197,8 @@ Parser::Parser(TranslationUnit *unit) _qtMocRunEnabled(false), _objCEnabled(false), _inFunctionBody(false), - _inObjCImplementationContext(false) + _inObjCImplementationContext(false), + _expressionDepth(0) { } Parser::~Parser() @@ -161,50 +238,48 @@ bool Parser::skipUntil(int token) return false; } -bool Parser::skipUntilDeclaration() +void Parser::skipUntilDeclaration() { - while (int tk = LA()) { - switch (tk) { - case T_SEMICOLON: - case T_TILDE: - case T_COLON_COLON: - case T_IDENTIFIER: - case T_OPERATOR: - case T_CHAR: - case T_WCHAR_T: - case T_BOOL: - case T_SHORT: - case T_INT: - case T_LONG: - case T_SIGNED: - case T_UNSIGNED: - case T_FLOAT: - case T_DOUBLE: - case T_VOID: - case T_EXTERN: - case T_NAMESPACE: - case T_USING: - case T_TYPEDEF: - case T_ASM: - case T_TEMPLATE: - case T_EXPORT: - case T_CONST: - case T_VOLATILE: - case T_PUBLIC: - case T_PROTECTED: - case T_PRIVATE: - case T_CLASS: - case T_STRUCT: - case T_UNION: - case T_TYPENAME: - return true; + for (; ; consumeToken()) { + switch (LA()) { + case T_EOF_SYMBOL: - default: - consumeToken(); - } - } + // names + case T_IDENTIFIER: + case T_COLON_COLON: + case T_TILDE: + case T_OPERATOR: - return false; + // empty declaration + case T_SEMICOLON: + + // member specification + case T_USING: + case T_TEMPLATE: + case T_PUBLIC: + case T_PROTECTED: + case T_PRIVATE: + case T_Q_SIGNALS: + case T_Q_SLOTS: + + // declarations + case T_ENUM: + case T_NAMESPACE: + case T_ASM: + case T_EXPORT: + case T_AT_CLASS: + case T_AT_INTERFACE: + case T_AT_PROTOCOL: + case T_AT_IMPLEMENTATION: + case T_AT_END: + return; + + default: + if (lookAtBuiltinTypeSpecifier() || lookAtClassKey() || + lookAtFunctionSpecifier() || lookAtStorageClassSpecifier()) + return; + } // switch + } } bool Parser::skipUntilStatement() @@ -334,7 +409,7 @@ bool Parser::parseTemplateId(NameAST *&node) ast->identifier_token = consumeToken(); ast->less_token = consumeToken(); if (LA() == T_GREATER || parseTemplateArgumentList( - ast->template_arguments)) { + ast->template_argument_list)) { if (LA() == T_GREATER) { ast->greater_token = consumeToken(); node = ast; @@ -348,28 +423,30 @@ bool Parser::parseTemplateId(NameAST *&node) return false; } -bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node, +bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node, bool /*acceptTemplateId*/) { DEBUG_THIS_RULE(); - NestedNameSpecifierAST **nested_name_specifier = &node; + NestedNameSpecifierListAST **nested_name_specifier = &node; NameAST *class_or_namespace_name = 0; - if (parseClassOrNamespaceName(class_or_namespace_name) && - LA() == T_COLON_COLON) { + if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) { unsigned scope_token = consumeToken(); - *nested_name_specifier = new (_pool) NestedNameSpecifierAST; - (*nested_name_specifier)->class_or_namespace_name - = class_or_namespace_name; - (*nested_name_specifier)->scope_token = scope_token; + NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST; + name->class_or_namespace_name = class_or_namespace_name; + name->scope_token = scope_token; + + *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name); nested_name_specifier = &(*nested_name_specifier)->next; - while (parseClassOrNamespaceName(class_or_namespace_name) && - LA() == T_COLON_COLON) { + while (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) { scope_token = consumeToken(); - *nested_name_specifier = new (_pool) NestedNameSpecifierAST; - (*nested_name_specifier)->class_or_namespace_name = class_or_namespace_name; - (*nested_name_specifier)->scope_token = scope_token; + + name = new (_pool) NestedNameSpecifierAST; + name->class_or_namespace_name = class_or_namespace_name; + name->scope_token = scope_token; + + *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name); nested_name_specifier = &(*nested_name_specifier)->next; } @@ -382,8 +459,7 @@ bool Parser::parseNestedNameSpecifier(NestedNameSpecifierAST *&node, return false; } -bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, - bool acceptTemplateId) +bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId) { DEBUG_THIS_RULE(); unsigned start = cursor(); @@ -399,7 +475,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId) if (LA() == T_COLON_COLON) global_scope_token = consumeToken(); - NestedNameSpecifierAST *nested_name_specifier = 0; + NestedNameSpecifierListAST *nested_name_specifier = 0; parseNestedNameSpecifierOpt(nested_name_specifier, /*acceptTemplateId=*/ true); @@ -413,7 +489,7 @@ bool Parser::parseName(NameAST *&node, bool acceptTemplateId) QualifiedNameAST *ast = new (_pool) QualifiedNameAST; ast->global_scope_token = global_scope_token; - ast->nested_name_specifier = nested_name_specifier; + ast->nested_name_specifier_list = nested_name_specifier; ast->unqualified_name = unqualified_name; node = ast; return true; @@ -426,7 +502,7 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node) { DEBUG_THIS_RULE(); TranslationUnitAST *ast = new (_pool) TranslationUnitAST; - DeclarationListAST **decl = &ast->declarations; + DeclarationListAST **decl = &ast->declaration_list; while (LA()) { unsigned start_declaration = cursor(); @@ -435,9 +511,10 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node) if (parseDeclaration(declaration)) { *decl = new (_pool) DeclarationListAST; - (*decl)->declaration = declaration; + (*decl)->value = declaration; decl = &(*decl)->next; } else { + _translationUnit->error(start_declaration, "expected a declaration"); rewind(start_declaration + 1); skipUntilDeclaration(); } @@ -503,7 +580,7 @@ bool Parser::parseDeclaration(DeclarationAST *&node) default: { if (_objCEnabled && LA() == T___ATTRIBUTE__) { const unsigned start = cursor(); - SpecifierAST *attributes = 0, **attr = &attributes; + SpecifierListAST *attributes = 0, **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; if (LA() == T_AT_INTERFACE) @@ -554,7 +631,7 @@ bool Parser::parseLinkageBody(DeclarationAST *&node) if (LA() == T_LBRACE) { LinkageBodyAST *ast = new (_pool) LinkageBodyAST; ast->lbrace_token = consumeToken(); - DeclarationListAST **declaration_ptr = &ast->declarations; + DeclarationListAST **declaration_ptr = &ast->declaration_list; while (int tk = LA()) { if (tk == T_RBRACE) @@ -564,9 +641,10 @@ bool Parser::parseLinkageBody(DeclarationAST *&node) DeclarationAST *declaration = 0; if (parseDeclaration(declaration)) { *declaration_ptr = new (_pool) DeclarationListAST; - (*declaration_ptr)->declaration = declaration; + (*declaration_ptr)->value = declaration; declaration_ptr = &(*declaration_ptr)->next; } else { + _translationUnit->error(start_declaration, "expected a declaration"); rewind(start_declaration + 1); skipUntilDeclaration(); } @@ -605,7 +683,7 @@ bool Parser::parseNamespace(DeclarationAST *&node) ast->namespace_token = namespace_token; if (LA() == T_IDENTIFIER) ast->identifier_token = consumeToken(); - SpecifierAST **attr_ptr = &ast->attributes; + SpecifierListAST **attr_ptr = &ast->attribute_list; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attr_ptr); attr_ptr = &(*attr_ptr)->next; @@ -660,18 +738,18 @@ bool Parser::parseConversionFunctionId(NameAST *&node) if (LA() != T_OPERATOR) return false; unsigned operator_token = consumeToken(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (! parseTypeSpecifier(type_specifier)) { return false; } - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; ConversionFunctionIdAST *ast = new (_pool) ConversionFunctionIdAST; ast->operator_token = operator_token; - ast->type_specifier = type_specifier; - ast->ptr_operators = ptr_operators; + ast->type_specifier_list = type_specifier; + ast->ptr_operator_list = ptr_operators; node = ast; return true; } @@ -718,15 +796,14 @@ bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node) ExpressionAST *template_argument = 0; if (parseTemplateArgument(template_argument)) { *template_argument_ptr = new (_pool) TemplateArgumentListAST; - (*template_argument_ptr)->template_argument = template_argument; + (*template_argument_ptr)->value = template_argument; template_argument_ptr = &(*template_argument_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA if (parseTemplateArgument(template_argument)) { *template_argument_ptr = new (_pool) TemplateArgumentListAST; - (*template_argument_ptr)->comma_token = comma_token; - (*template_argument_ptr)->template_argument = template_argument; + (*template_argument_ptr)->value = template_argument; template_argument_ptr = &(*template_argument_ptr)->next; } } @@ -852,7 +929,7 @@ bool Parser::parseTemplateDeclaration(DeclarationAST *&node) if (LA() == T_LESS) { ast->less_token = consumeToken(); - if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameters)) + if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list)) match(T_GREATER, &ast->greater_token); } @@ -933,11 +1010,13 @@ bool Parser::parseOperator(OperatorAST *&node) // ### FIXME return true; } -bool Parser::parseCvQualifiers(SpecifierAST *&node) +bool Parser::parseCvQualifiers(SpecifierListAST *&node) { DEBUG_THIS_RULE(); + unsigned start = cursor(); - SpecifierAST **ast = &node; + + SpecifierListAST **ast = &node; while (*ast) ast = &(*ast)->next; @@ -945,7 +1024,7 @@ bool Parser::parseCvQualifiers(SpecifierAST *&node) if (tk == T_CONST || tk == T_VOLATILE) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *ast = spec; + *ast = new (_pool) SpecifierListAST(spec); ast = &(*ast)->next; } else if(LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*ast); @@ -958,19 +1037,19 @@ bool Parser::parseCvQualifiers(SpecifierAST *&node) return start != cursor(); } -bool Parser::parsePtrOperator(PtrOperatorAST *&node) +bool Parser::parsePtrOperator(PtrOperatorListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_AMPER) { ReferenceAST *ast = new (_pool) ReferenceAST; ast->amp_token = consumeToken(); - node = ast; + node = new (_pool) PtrOperatorListAST(ast); return true; } else if (LA() == T_STAR) { PointerAST *ast = new (_pool) PointerAST; ast->star_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - node = ast; + parseCvQualifiers(ast->cv_qualifier_list); + node = new (_pool) PtrOperatorListAST(ast); return true; } else if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER) { unsigned scope_or_identifier_token = cursor(); @@ -979,16 +1058,15 @@ bool Parser::parsePtrOperator(PtrOperatorAST *&node) if (LA() == T_COLON_COLON) global_scope_token = consumeToken(); - NestedNameSpecifierAST *nested_name_specifier = 0; - bool has_nested_name_specifier = parseNestedNameSpecifier( - nested_name_specifier, true); + NestedNameSpecifierListAST *nested_name_specifiers = 0; + bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true); if (has_nested_name_specifier && LA() == T_STAR) { PointerToMemberAST *ast = new (_pool) PointerToMemberAST; ast->global_scope_token = global_scope_token; - ast->nested_name_specifier = nested_name_specifier; + ast->nested_name_specifier_list = nested_name_specifiers; ast->star_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - node = ast; + parseCvQualifiers(ast->cv_qualifier_list); + node = new (_pool) PtrOperatorListAST(ast); return true; } rewind(scope_or_identifier_token); @@ -1010,24 +1088,24 @@ bool Parser::parseTemplateArgument(ExpressionAST *&node) return parsed; } -bool Parser::parseDeclSpecifierSeq(SpecifierAST *&decl_specifier_seq, +bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq, bool onlyTypeSpecifiers, bool simplified) { DEBUG_THIS_RULE(); bool has_type_specifier = false; NameAST *named_type_specifier = 0; - SpecifierAST **decl_specifier_seq_ptr = &decl_specifier_seq; + SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq; for (;;) { if (lookAtCVQualifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (! onlyTypeSpecifiers && lookAtStorageClassSpecifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (! named_type_specifier && lookAtBuiltinTypeSpecifier()) { parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr); @@ -1039,7 +1117,7 @@ bool Parser::parseDeclSpecifierSeq(SpecifierAST *&decl_specifier_seq, return false; NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; spec->name = named_type_specifier; - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; } else if (! simplified && ! has_type_specifier && (LA() == T_TYPENAME || @@ -1078,14 +1156,14 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) { DEBUG_THIS_RULE(); unsigned start = cursor(); - SpecifierAST *attributes = 0; - SpecifierAST **attribute_ptr = &attributes; + SpecifierListAST *attributes = 0; + SpecifierListAST **attribute_ptr = &attributes; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attribute_ptr); attribute_ptr = &(*attribute_ptr)->next; } - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; @@ -1096,8 +1174,8 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) DeclaratorIdAST *declarator_id = new (_pool) DeclaratorIdAST; declarator_id->name = name; DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->attributes = attributes; - ast->ptr_operators = ptr_operators; + ast->attribute_list = attributes; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = declarator_id; node = ast; return true; @@ -1114,7 +1192,7 @@ bool Parser::parseCoreDeclarator(DeclaratorAST *&node) nested_declarator->declarator = declarator; nested_declarator->rparen_token = consumeToken(); DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = nested_declarator; node = ast; return true; @@ -1130,7 +1208,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) if (! parseCoreDeclarator(node)) return false; - PostfixDeclaratorAST **postfix_ptr = &node->postfix_declarators; + PostfixDeclaratorListAST **postfix_ptr = &node->postfix_declarator_list; for (;;) { unsigned startOfPostDeclarator = cursor(); @@ -1158,7 +1236,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) ast->parameters = parameter_declaration_clause; ast->as_cpp_initializer = initializer; ast->rparen_token = rparen_token; - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; blockErrors(blocked); @@ -1186,9 +1264,9 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) } ast->rparen_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); + parseCvQualifiers(ast->cv_qualifier_list); parseExceptionSpecification(ast->exception_specification); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST; @@ -1196,7 +1274,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) { match(T_RBRACKET, &ast->rbracket_token); } - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; @@ -1210,7 +1288,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) consumeToken(); // skip T_RPAREN } - SpecifierAST **spec_ptr = &node->post_attributes; + SpecifierListAST **spec_ptr = &node->post_attribute_list; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*spec_ptr); spec_ptr = &(*spec_ptr)->next; @@ -1222,7 +1300,8 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer) bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) { DEBUG_THIS_RULE(); - PtrOperatorAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; + + PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators; while (parsePtrOperator(*ptr_operators_tail)) ptr_operators_tail = &(*ptr_operators_tail)->next; @@ -1237,7 +1316,7 @@ bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) nested_declarator->declarator = declarator; nested_declarator->rparen_token = consumeToken(); DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; ast->core_declarator = nested_declarator; node = ast; return true; @@ -1247,7 +1326,7 @@ bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node) rewind(after_ptr_operators); if (ptr_operators) { DeclaratorAST *ast = new (_pool) DeclaratorAST; - ast->ptr_operators = ptr_operators; + ast->ptr_operator_list = ptr_operators; node = ast; } @@ -1260,7 +1339,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (! parseAbstractCoreDeclarator(node)) return false; - PostfixDeclaratorAST *postfix_declarators = 0, + PostfixDeclaratorListAST *postfix_declarators = 0, **postfix_ptr = &postfix_declarators; for (;;) { @@ -1271,9 +1350,9 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (LA() == T_RPAREN) ast->rparen_token = consumeToken(); } - parseCvQualifiers(ast->cv_qualifier_seq); + parseCvQualifiers(ast->cv_qualifier_list); parseExceptionSpecification(ast->exception_specification); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST; @@ -1282,7 +1361,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (LA() == T_RBRACKET) ast->rbracket_token = consumeToken(); } - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; @@ -1292,13 +1371,13 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) if (! node) node = new (_pool) DeclaratorAST; - node->postfix_declarators = postfix_declarators; + node->postfix_declarator_list = postfix_declarators; } return true; } -bool Parser::parseEnumSpecifier(SpecifierAST *&node) +bool Parser::parseEnumSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_ENUM) { @@ -1311,7 +1390,7 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) ast->name = name; ast->lbrace_token = consumeToken(); unsigned comma_token = 0; - EnumeratorAST **enumerator_ptr = &ast->enumerators; + EnumeratorListAST **enumerator_ptr = &ast->enumerator_list; while (int tk = LA()) { if (tk == T_RBRACE) break; @@ -1322,7 +1401,6 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) } if (parseEnumerator(*enumerator_ptr)) { - (*enumerator_ptr)->comma_token = comma_token; enumerator_ptr = &(*enumerator_ptr)->next; } @@ -1330,7 +1408,7 @@ bool Parser::parseEnumSpecifier(SpecifierAST *&node) match(T_COMMA, &comma_token); } match(T_RBRACE, &ast->rbrace_token); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } } @@ -1344,7 +1422,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node) DeclarationAST *declaration = 0; if (parseTemplateParameter(declaration)) { *template_parameter_ptr = new (_pool) DeclarationListAST; - (*template_parameter_ptr)->declaration = declaration; + (*template_parameter_ptr)->value = declaration; template_parameter_ptr = &(*template_parameter_ptr)->next; while (LA() == T_COMMA) { @@ -1353,7 +1431,7 @@ bool Parser::parseTemplateParameterList(DeclarationListAST *&node) declaration = 0; if (parseTemplateParameter(declaration)) { *template_parameter_ptr = new (_pool) DeclarationListAST; - (*template_parameter_ptr)->declaration = declaration; + (*template_parameter_ptr)->value = declaration; template_parameter_ptr = &(*template_parameter_ptr)->next; } } @@ -1398,7 +1476,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node) ast->template_token = consumeToken(); if (LA() == T_LESS) ast->less_token = consumeToken(); - parseTemplateParameterList(ast->template_parameters); + parseTemplateParameterList(ast->template_parameter_list); if (LA() == T_GREATER) ast->greater_token = consumeToken(); if (LA() == T_CLASS) @@ -1431,10 +1509,10 @@ bool Parser::parseTypeParameter(DeclarationAST *&node) bool Parser::parseTypeId(ExpressionAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { TypeIdAST *ast = new (_pool) TypeIdAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; parseAbstractDeclarator(ast->declarator); node = ast; return true; @@ -1466,7 +1544,7 @@ bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&nod if (parameter_declarations || dot_dot_dot_token) { ParameterDeclarationClauseAST *ast = new (_pool) ParameterDeclarationClauseAST; - ast->parameter_declarations = parameter_declarations; + ast->parameter_declaration_list = parameter_declarations; ast->dot_dot_dot_token = dot_dot_dot_token; node = ast; } @@ -1484,7 +1562,7 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) DeclarationAST *declaration = 0; if (parseParameterDeclaration(declaration)) { *parameter_declaration_ptr = new (_pool) DeclarationListAST; - (*parameter_declaration_ptr)->declaration = declaration; + (*parameter_declaration_ptr)->value = declaration; parameter_declaration_ptr = &(*parameter_declaration_ptr)->next; while (LA() == T_COMMA) { consumeToken(); @@ -1495,7 +1573,7 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) declaration = 0; if (parseParameterDeclaration(declaration)) { *parameter_declaration_ptr = new (_pool) DeclarationListAST; - (*parameter_declaration_ptr)->declaration = declaration; + (*parameter_declaration_ptr)->value = declaration; parameter_declaration_ptr = &(*parameter_declaration_ptr)->next; } } @@ -1507,10 +1585,10 @@ bool Parser::parseParameterDeclarationList(DeclarationListAST *&node) bool Parser::parseParameterDeclaration(DeclarationAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *decl_specifier_seq = 0; + SpecifierListAST *decl_specifier_seq = 0; if (parseDeclSpecifierSeq(decl_specifier_seq)) { ParameterDeclarationAST *ast = new (_pool) ParameterDeclarationAST; - ast->type_specifier = decl_specifier_seq; + ast->type_specifier_list = decl_specifier_seq; parseDeclaratorOrAbstractDeclarator(ast->declarator); if (LA() == T_EQUAL) { ast->equal_token = consumeToken(); @@ -1523,7 +1601,7 @@ bool Parser::parseParameterDeclaration(DeclarationAST *&node) return false; } -bool Parser::parseClassSpecifier(SpecifierAST *&node) +bool Parser::parseClassSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (! lookAtClassKey()) @@ -1531,7 +1609,7 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) unsigned classkey_token = consumeToken(); - SpecifierAST *attributes = 0, **attr_ptr = &attributes; + SpecifierListAST *attributes = 0, **attr_ptr = &attributes; while (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*attr_ptr); attr_ptr = &(*attr_ptr)->next; @@ -1554,17 +1632,23 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) unsigned colon_token = 0; if (LA() == T_COLON || LA() == T_LBRACE) { - BaseSpecifierAST *base_clause = 0; + BaseSpecifierListAST *base_clause_list = 0; + if (LA() == T_COLON) { colon_token = cursor(); - parseBaseClause(base_clause); + + parseBaseClause(base_clause_list); + if (LA() != T_LBRACE) { _translationUnit->error(cursor(), "expected `{' before `%s'", tok().spell()); - unsigned saved = cursor(); + + const unsigned saved = cursor(); + for (int n = 0; n < 3 && LA() != T_EOF_SYMBOL; ++n, consumeToken()) { if (LA() == T_LBRACE) break; } + if (LA() != T_LBRACE) rewind(saved); } @@ -1572,15 +1656,15 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST; ast->classkey_token = classkey_token; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->name = name; ast->colon_token = colon_token; - ast->base_clause = base_clause; + ast->base_clause_list = base_clause_list; if (LA() == T_LBRACE) ast->lbrace_token = consumeToken(); - DeclarationListAST **declaration_ptr = &ast->member_specifiers; + DeclarationListAST **declaration_ptr = &ast->member_specifier_list; while (int tk = LA()) { if (tk == T_RBRACE) { ast->rbrace_token = consumeToken(); @@ -1590,15 +1674,23 @@ bool Parser::parseClassSpecifier(SpecifierAST *&node) unsigned start_declaration = cursor(); DeclarationAST *declaration = 0; if (parseMemberSpecification(declaration)) { - *declaration_ptr = new (_pool) DeclarationListAST; - (*declaration_ptr)->declaration = declaration; - declaration_ptr = &(*declaration_ptr)->next; + if (declaration) { // paranoia check + *declaration_ptr = new (_pool) DeclarationListAST; + (*declaration_ptr)->value = declaration; + declaration_ptr = &(*declaration_ptr)->next; + } + + if (cursor() == start_declaration) { // more paranoia + rewind(start_declaration + 1); + skipUntilDeclaration(); + } } else { + _translationUnit->error(start_declaration, "expected a declaration"); rewind(start_declaration + 1); skipUntilDeclaration(); } } - node = ast; + node = new (_pool) SpecifierListAST(ast); parsed = true; } @@ -1641,6 +1733,158 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node) return false; } +#ifdef ICHECK_BUILD +bool Parser::parseQPropertyDeclaration(DeclarationAST *&node) +{ + /* + Q_PROPERTY(type name + READ getFunction + [WRITE setFunction] + [RESET resetFunction] + [NOTIFY notifySignal] + [DESIGNABLE bool] + [SCRIPTABLE bool] + [STORED bool] + [USER bool] + [CONSTANT] + [FINAL])*/ + DEBUG_THIS_RULE(); + if (LA() == T_Q_PROPERTY) { + QPropertyDeclarationAST *ast = new (_pool)QPropertyDeclarationAST; + ast->property_specifier_token = consumeToken(); + if(LA() == T_LPAREN){ + ast->lparen_token = consumeToken(); + QString tokenstr; + tokenstr = tok().spell(); + //read the type and the name of the type + if(tokenstr != "READ" ){ + ast->type_token = consumeToken(); + tokenstr = tok().spell(); + } + if(tokenstr != "READ" ){ + ast->type_name_token = consumeToken(); + tokenstr = tok().spell(); + } + unsigned fctdefinition = 0; + unsigned fctname = 0; + for(int i = 0; i < 18; i++){ + if(cursor() < _translationUnit->tokenCount() - 1){ + if(LA() == T_RPAREN){ + ast->rparen_token = consumeToken(); + break; + } + tokenstr = tok().spell(); + fctdefinition = consumeToken(); + fctname = consumeToken(); + if(tokenstr == "READ"){ + ast->read_token = fctdefinition; + ast->read_function_token = fctname; + } + else if(tokenstr == "WRITE"){ + ast->write_token = fctdefinition; + ast->write_function_token = fctname; + } + else if(tokenstr == "RESET"){ + ast->reset_token = fctdefinition; + ast->reset_function_token = fctname; + } + else if(tokenstr == "NOTIFY"){ + ast->notify_token = fctdefinition; + ast->notify_function_token = fctname; + } + } + } + } + node = ast; + return true; + } + return false; +} + +bool Parser::parseQEnumDeclaration(DeclarationAST *&node) +{ + /*Q_ENUMS(ConnectionState)*/ + DEBUG_THIS_RULE(); + if (LA() == T_Q_ENUMS) { + QEnumDeclarationAST *ast = new (_pool)QEnumDeclarationAST; + ast->enum_specifier_token = consumeToken(); + EnumeratorListAST** enumerator_list_ptr; + enumerator_list_ptr = &ast->enumerator_list; + + if(LA() == T_LPAREN){ + ast->lparen_token = consumeToken(); + while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){ + *enumerator_list_ptr = new (_pool) EnumeratorListAST; + EnumeratorAST *pdecl = new (_pool) EnumeratorAST; + pdecl->identifier_token = consumeToken(); + (*enumerator_list_ptr)->value = pdecl; + enumerator_list_ptr = &(*enumerator_list_ptr)->next; + if (LA() == T_COMMA) + consumeToken(); + } + if(LA() == T_RPAREN) + ast->rparen_token = consumeToken(); + } + node = ast; + return true; + } + return false; +} + +bool Parser::parseQFlags(DeclarationAST *&node) +{ + /*Q_FLAGS(enum1 enum2 flags1)*/ + DEBUG_THIS_RULE(); + if (LA() == T_Q_FLAGS) { + QFlagsDeclarationAST *ast = new (_pool)QFlagsDeclarationAST; + ast->flags_specifier_token = consumeToken(); + EnumeratorListAST** enumerator_list_ptr; + enumerator_list_ptr = &ast->enumerator_list; + if(LA() == T_LPAREN){ + ast->lparen_token = consumeToken(); + while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){ + *enumerator_list_ptr = new (_pool) EnumeratorListAST; + EnumeratorAST *pdecl = new (_pool) EnumeratorAST; + pdecl->identifier_token = consumeToken(); + (*enumerator_list_ptr)->value = pdecl; + enumerator_list_ptr = &(*enumerator_list_ptr)->next; + if (LA() == T_COMMA) + consumeToken(); + } + if(LA() == T_RPAREN) + ast->rparen_token = consumeToken(); + } + node = ast; + return true; + } + return false; +} + +bool Parser::parseQDeclareFlags(DeclarationAST *&node) +{ + /*Q_DECLARE_FLAGS(flag enum)*/ + DEBUG_THIS_RULE(); + if (LA() == T_Q_DECLARE_FLAGS) { + QDeclareFlagsDeclarationAST *ast = new (_pool)QDeclareFlagsDeclarationAST; + ast->declareflags_specifier_token = consumeToken(); + if(LA() == T_LPAREN){ + ast->lparen_token = consumeToken(); + if(LA() != T_EOF_SYMBOL) + ast->flag_token = consumeToken(); + if(LA() == T_COMMA && LA() != T_EOF_SYMBOL) + consumeToken(); + if(LA() != T_EOF_SYMBOL) + ast->enum_token = consumeToken(); + if(LA() != T_EOF_SYMBOL && LA() == T_RPAREN) + ast->rparen_token = consumeToken(); + } + node = ast; + return true; + } + return false; +} +#endif + bool Parser::parseMemberSpecification(DeclarationAST *&node) { DEBUG_THIS_RULE(); @@ -1660,6 +1904,20 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node) case T_PRIVATE: return parseAccessDeclaration(node); +#ifdef ICHECK_BUILD + case T_Q_PROPERTY: + return parseQPropertyDeclaration(node); + + case T_Q_ENUMS: + return parseQEnumDeclaration(node); + + case T_Q_FLAGS: + return parseQFlags(node); + + case T_Q_DECLARE_FLAGS: + return parseQDeclareFlags(node); +#endif + default: return parseSimpleDeclaration(node, /*acceptStructDeclarator=*/true); } // switch @@ -1674,26 +1932,24 @@ bool Parser::parseCtorInitializer(CtorInitializerAST *&node) CtorInitializerAST *ast = new (_pool) CtorInitializerAST; ast->colon_token = colon_token; - parseMemInitializerList(ast->member_initializers); + parseMemInitializerList(ast->member_initializer_list); node = ast; return true; } return false; } -bool Parser::parseElaboratedTypeSpecifier(SpecifierAST *&node) +bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (lookAtClassKey() || LA() == T_ENUM || LA() == T_TYPENAME) { unsigned classkey_token = consumeToken(); NameAST *name = 0; if (parseName(name)) { - ElaboratedTypeSpecifierAST *ast = - new (_pool) ElaboratedTypeSpecifierAST; - + ElaboratedTypeSpecifierAST *ast = new (_pool) ElaboratedTypeSpecifierAST; ast->classkey_token = classkey_token; ast->name = name; - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } } @@ -1711,7 +1967,7 @@ bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) if (LA() == T_DOT_DOT_DOT) ast->dot_dot_dot_token = consumeToken(); else - parseTypeIdList(ast->type_ids); + parseTypeIdList(ast->type_id_list); if (LA() == T_RPAREN) ast->rparen_token = consumeToken(); node = ast; @@ -1720,7 +1976,7 @@ bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) return false; } -bool Parser::parseEnumerator(EnumeratorAST *&node) +bool Parser::parseEnumerator(EnumeratorListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_IDENTIFIER) { @@ -1731,7 +1987,9 @@ bool Parser::parseEnumerator(EnumeratorAST *&node) ast->equal_token = consumeToken(); parseConstantExpression(ast->expression); } - node = ast; + + node = new (_pool) EnumeratorListAST; + node->value = ast; return true; } return false; @@ -1758,7 +2016,7 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, } if (acceptStructDeclarator && node && - ! node->postfix_declarators && + ! node->postfix_declarator_list && node->core_declarator && node->core_declarator->asNestedDeclarator()) { rewind(start); @@ -1766,7 +2024,7 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, } if (acceptStructDeclarator && LA() == T_COLON - && (! node || ! node->postfix_declarators)) { + && (! node || ! node->postfix_declarator_list)) { unsigned colon_token = consumeToken(); ExpressionAST *expression = 0; if (parseConstantExpression(expression) && (LA() == T_COMMA || @@ -1782,23 +2040,22 @@ bool Parser::parseInitDeclarator(DeclaratorAST *&node, return true; } -bool Parser::parseBaseClause(BaseSpecifierAST *&node) +bool Parser::parseBaseClause(BaseSpecifierListAST *&node) { DEBUG_THIS_RULE(); + if (LA() == T_COLON) { - consumeToken(); + consumeToken(); // ### remove me - BaseSpecifierAST **ast = &node; + BaseSpecifierListAST **ast = &node; if (parseBaseSpecifier(*ast)) { ast = &(*ast)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA - if (parseBaseSpecifier(*ast)) { - (*ast)->comma_token = comma_token; + if (parseBaseSpecifier(*ast)) ast = &(*ast)->next; - } } } @@ -1819,41 +2076,58 @@ bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token) return false; } -bool Parser::parseMemInitializerList(MemInitializerAST *&node) +bool Parser::parseMemInitializerList(MemInitializerListAST *&node) { DEBUG_THIS_RULE(); - MemInitializerAST **initializer = &node; + MemInitializerListAST **initializer = &node; if (parseMemInitializer(*initializer)) { initializer = &(*initializer)->next; - while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); - if (parseMemInitializer(*initializer)) { - (*initializer)->comma_token = comma_token; - initializer = &(*initializer)->next; - } + while (true) { + + if (LA() == T_LBRACE) + break; + + else if (LA() == T_COMMA || (LA() == T_IDENTIFIER && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON))) { + if (LA() != T_COMMA) + _translationUnit->error(cursor(), "expected `,'"); + else + consumeToken(); + + if (parseMemInitializer(*initializer)) + initializer = &(*initializer)->next; + else + _translationUnit->error(cursor(), "expected a member initializer"); + + } else break; } + + if (LA() != T_LBRACE) + _translationUnit->error(cursor(), "expected `{'"); + return true; } + return false; } -bool Parser::parseMemInitializer(MemInitializerAST *&node) +bool Parser::parseMemInitializer(MemInitializerListAST *&node) { DEBUG_THIS_RULE(); NameAST *name = 0; - if (parseName(name) && LA() == T_LPAREN) { - MemInitializerAST *ast = new (_pool) MemInitializerAST; - ast->name = name; - ast->lparen_token = consumeToken(); - parseExpression(ast->expression); - if (LA() == T_RPAREN) - ast->rparen_token = consumeToken(); - node = ast; - return true; - } - return false; + if (! parseName(name)) + return false; + + MemInitializerAST *ast = new (_pool) MemInitializerAST; + ast->name = name; + match(T_LPAREN, &ast->lparen_token); + parseExpressionList(ast->expression_list); + match(T_RPAREN, &ast->rparen_token); + + node = new (_pool) MemInitializerListAST; + node->value = ast; + return true; } bool Parser::parseTypeIdList(ExpressionListAST *&node) @@ -1863,14 +2137,14 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node) ExpressionAST *typeId = 0; if (parseTypeId(typeId)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = typeId; + (*expression_list_ptr)->value = typeId; expression_list_ptr = &(*expression_list_ptr)->next; while (LA() == T_COMMA) { consumeToken(); if (parseTypeId(typeId)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = typeId; + (*expression_list_ptr)->value = typeId; expression_list_ptr = &(*expression_list_ptr)->next; } } @@ -1887,15 +2161,14 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) ExpressionAST *expression = 0; if (parseAssignmentExpression(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->expression = expression; + (*expression_list_ptr)->value = expression; expression_list_ptr = &(*expression_list_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA - if (parseExpression(expression)) { + if (parseAssignmentExpression(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; - (*expression_list_ptr)->comma_token = comma_token; - (*expression_list_ptr)->expression = expression; + (*expression_list_ptr)->value = expression; expression_list_ptr = &(*expression_list_ptr)->next; } } @@ -1904,7 +2177,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node) return false; } -bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) +bool Parser::parseBaseSpecifier(BaseSpecifierListAST *&node) { DEBUG_THIS_RULE(); BaseSpecifierAST *ast = new (_pool) BaseSpecifierAST; @@ -1927,7 +2200,9 @@ bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) parseName(ast->name); if (! ast->name) _translationUnit->error(cursor(), "expected class-name"); - node = ast; + + node = new (_pool) BaseSpecifierListAST; + node->value = ast; return true; } @@ -1938,15 +2213,14 @@ bool Parser::parseInitializerList(ExpressionListAST *&node) ExpressionAST *initializer = 0; if (parseInitializerClause(initializer)) { *initializer_ptr = new (_pool) ExpressionListAST; - (*initializer_ptr)->expression = initializer; + (*initializer_ptr)->value = initializer; initializer_ptr = &(*initializer_ptr)->next; while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA initializer = 0; parseInitializerClause(initializer); *initializer_ptr = new (_pool) ExpressionListAST; - (*initializer_ptr)->comma_token = comma_token; - (*initializer_ptr)->expression = initializer; + (*initializer_ptr)->value = initializer; initializer_ptr = &(*initializer_ptr)->next; } } @@ -2096,6 +2370,16 @@ bool Parser::parseStatement(StatementAST *&node) if (objCEnabled()) return parseObjCSynchronizedStatement(node); + case T_Q_D: + case T_Q_Q: { + QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST; + ast->q_token = consumeToken(); + match(T_LPAREN, &ast->lparen_token); + parseTypeId(ast->type_id); + match(T_RPAREN, &ast->rparen_token); + node = ast; + } return true; + default: if (LA() == T_IDENTIFIER && LA(2) == T_COLON) return parseLabeledStatement(node); @@ -2165,11 +2449,11 @@ bool Parser::isPointerDeclaration(DeclarationStatementAST *ast) const return false; if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) { - if (SpecifierAST *spec = declaration->decl_specifier_seq) { - if (spec->asNamedTypeSpecifier() && ! spec->next) { - if (DeclaratorListAST *declarators = declaration->declarators) { - if (DeclaratorAST *declarator = declarators->declarator) { - if (declarator->ptr_operators && declarator->equals_token && declarator->initializer) { + if (SpecifierListAST *spec = declaration->decl_specifier_list) { + if (spec->value->asNamedTypeSpecifier() && ! spec->next) { + if (DeclaratorListAST *declarators = declaration->declarator_list) { + if (DeclaratorAST *declarator = declarators->value) { + if (declarator->ptr_operator_list && declarator->equals_token && declarator->initializer) { return true; } } @@ -2187,10 +2471,10 @@ bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast) const return false; if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) { - if (SpecifierAST *spec = declaration->decl_specifier_seq) { - if (spec->asNamedTypeSpecifier() && ! spec->next) { - if (DeclaratorListAST *declarators = declaration->declarators) { - if (DeclaratorAST *declarator = declarators->declarator) { + if (SpecifierListAST *spec = declaration->decl_specifier_list) { + if (spec->value->asNamedTypeSpecifier() && ! spec->next) { + if (DeclaratorListAST *declarators = declaration->declarator_list) { + if (DeclaratorAST *declarator = declarators->value) { if (declarator->core_declarator && declarator->core_declarator->asNestedDeclarator()) { // recognized name(id-expression) @@ -2200,10 +2484,10 @@ bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast) const } } - } else if (DeclaratorListAST *declarators = declaration->declarators) { + } else if (DeclaratorListAST *declarators = declaration->declarator_list) { // no decl_specifiers... - if (DeclaratorAST *declarator = declarators->declarator) { - if (declarator->postfix_declarators && declarator->postfix_declarators->asFunctionDeclarator() + if (DeclaratorAST *declarator = declarators->value) { + if (declarator->postfix_declarator_list && declarator->postfix_declarator_list->value->asFunctionDeclarator() && ! declarator->initializer) { return false; } @@ -2264,13 +2548,13 @@ bool Parser::parseCondition(ExpressionAST *&node) unsigned start = cursor(); bool blocked = blockErrors(true); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { DeclaratorAST *declarator = 0; if (parseInitDeclarator(declarator, /*acceptStructDeclarator=*/false)) { if (declarator->initializer) { ConditionAST *ast = new (_pool) ConditionAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; ast->declarator = declarator; node = ast; blockErrors(blocked); @@ -2329,11 +2613,11 @@ bool Parser::parseForeachStatement(StatementAST *&node) unsigned startOfTypeSpecifier = cursor(); bool blocked = blockErrors(true); - if (parseTypeSpecifier(ast->type_specifiers)) + if (parseTypeSpecifier(ast->type_specifier_list)) parseDeclarator(ast->declarator); - if (! ast->type_specifiers || ! ast->declarator) { - ast->type_specifiers = 0; + if (! ast->type_specifier_list || ! ast->declarator) { + ast->type_specifier_list = 0; ast->declarator = 0; blockErrors(blocked); @@ -2372,20 +2656,20 @@ bool Parser::parseForStatement(StatementAST *&node) ast->for_token = for_token; ast->lparen_token = lparen_token; - if (parseTypeSpecifier(ast->type_specifiers)) + if (parseTypeSpecifier(ast->type_specifier_list)) parseDeclarator(ast->declarator); - if ((ast->type_specifiers || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) { + if ((ast->type_specifier_list || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) { // woops, probably parsed too much: "in" got parsed as a declarator. Let's redo it: - ast->type_specifiers = 0; + ast->type_specifier_list = 0; ast->declarator = 0; rewind(startOfTypeSpecifier); parseDeclarator(ast->declarator); } - if (! ast->type_specifiers || ! ast->declarator) { - ast->type_specifiers = 0; + if (! ast->type_specifier_list || ! ast->declarator) { + ast->type_specifier_list = 0; ast->declarator = 0; rewind(startOfTypeSpecifier); @@ -2397,7 +2681,7 @@ bool Parser::parseForStatement(StatementAST *&node) parseExpression(ast->fast_enumeratable_expression); match(T_RPAREN, &ast->rparen_token); - parseStatement(ast->body_statement); + parseStatement(ast->statement); node = ast; return true; @@ -2415,7 +2699,7 @@ bool Parser::parseForStatement(StatementAST *&node) ast->for_token = for_token; ast->lparen_token = lparen_token; parseForInitStatement(ast->initializer); - parseExpression(ast->condition); + parseCondition(ast->condition); match(T_SEMICOLON, &ast->semicolon_token); parseExpression(ast->expression); match(T_RPAREN, &ast->rparen_token); @@ -2437,7 +2721,7 @@ bool Parser::parseCompoundStatement(StatementAST *&node) if (LA() == T_LBRACE) { CompoundStatementAST *ast = new (_pool) CompoundStatementAST; ast->lbrace_token = consumeToken(); - StatementListAST **statement_ptr = &ast->statements; + StatementListAST **statement_ptr = &ast->statement_list; while (int tk = LA()) { if (tk == T_RBRACE) break; @@ -2449,7 +2733,7 @@ bool Parser::parseCompoundStatement(StatementAST *&node) skipUntilStatement(); } else { *statement_ptr = new (_pool) StatementListAST; - (*statement_ptr)->statement = statement; + (*statement_ptr)->value = statement; statement_ptr = &(*statement_ptr)->next; } } @@ -2582,7 +2866,7 @@ bool Parser::parseDeclarationStatement(StatementAST *&node) return false; if (SimpleDeclarationAST *simpleDeclaration = declaration->asSimpleDeclaration()) { - if (! simpleDeclaration->decl_specifier_seq) { + if (! simpleDeclaration->decl_specifier_list) { rewind(start); return false; } @@ -2669,7 +2953,7 @@ bool Parser::lookAtClassKey() const } } -bool Parser::parseAttributeSpecifier(SpecifierAST *&node) +bool Parser::parseAttributeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() != T___ATTRIBUTE__) @@ -2679,45 +2963,35 @@ bool Parser::parseAttributeSpecifier(SpecifierAST *&node) ast->attribute_token = consumeToken(); match(T_LPAREN, &ast->first_lparen_token); match(T_LPAREN, &ast->second_lparen_token); - parseAttributeList(ast->attributes); + parseAttributeList(ast->attribute_list); match(T_RPAREN, &ast->first_rparen_token); match(T_RPAREN, &ast->second_rparen_token); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } -bool Parser::parseAttributeList(AttributeAST *&node) +bool Parser::parseAttributeList(AttributeListAST *&) // ### create the AST { DEBUG_THIS_RULE(); - AttributeAST **attribute_ptr = &node; - while (LA() == T_IDENTIFIER || LA() == T_CONST) { - AttributeAST *ast = new (_pool) AttributeAST; - ast->identifier_token = consumeToken(); - if (LA() == T_LPAREN) { - ast->lparen_token = consumeToken(); - if (LA() == T_IDENTIFIER && (LA(2) == T_COMMA || LA(2) == T_RPAREN)) { - ast->tag_token = consumeToken(); - if (LA() == T_COMMA) { - ast->comma_token = consumeToken(); - parseExpressionList(ast->expression_list); - } - } else { - parseExpressionList(ast->expression_list); - } - match(T_RPAREN, &ast->rparen_token); + + while (LA() == T_CONST || LA() == T_IDENTIFIER) { + if (LA() == T_CONST) + consumeToken(); + else if (LA() == T_IDENTIFIER) { + ExpressionAST *expression = 0; + parseExpression(expression); } - *attribute_ptr = ast; if (LA() != T_COMMA) break; - consumeToken(); - attribute_ptr = &(*attribute_ptr)->next; + consumeToken(); // skip T_COMMA } + return true; } -bool Parser::parseBuiltinTypeSpecifier(SpecifierAST *&node) +bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T___ATTRIBUTE__) { @@ -2730,18 +3004,18 @@ bool Parser::parseBuiltinTypeSpecifier(SpecifierAST *&node) if (parseTypeId(ast->expression) && LA() == T_RPAREN) { ast->lparen_token = lparen_token; ast->rparen_token = consumeToken(); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } rewind(lparen_token); } parseUnaryExpression(ast->expression); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } else if (lookAtBuiltinTypeSpecifier()) { SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST; ast->specifier_token = consumeToken(); - node = ast; + node = new (_pool) SpecifierListAST(ast); return true; } return false; @@ -2754,6 +3028,11 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, unsigned qt_invokable_token = 0; if (acceptStructDeclarator && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT)) qt_invokable_token = consumeToken(); +#ifdef ICHECK_BUILD + unsigned invoke_token = 0; + if (LA() == T_Q_INVOKABLE) + invoke_token = consumeToken(); +#endif // parse a simple declaration, a function definition, // or a contructor declaration. @@ -2761,14 +3040,14 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, bool has_complex_type_specifier = false; unsigned startOfNamedTypeSpecifier = 0; NameAST *named_type_specifier = 0; - SpecifierAST *decl_specifier_seq = 0, + SpecifierListAST *decl_specifier_seq = 0, **decl_specifier_seq_ptr = &decl_specifier_seq; for (;;) { if (lookAtCVQualifier() || lookAtFunctionSpecifier() || lookAtStorageClassSpecifier()) { SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST; spec->specifier_token = consumeToken(); - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; } else if (LA() == T___ATTRIBUTE__) { parseAttributeSpecifier(*decl_specifier_seq_ptr); @@ -2783,7 +3062,7 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, if (parseName(named_type_specifier)) { NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST; spec->name = named_type_specifier; - *decl_specifier_seq_ptr = spec; + *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec); decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next; has_type_specifier = true; } else { @@ -2834,21 +3113,24 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, DeclaratorListAST *declarator_list = 0, **declarator_ptr = &declarator_list; - const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier); DeclaratorAST *declarator = 0; - if (! parseInitDeclarator(declarator, acceptStructDeclarator) && maybeCtor) { - rewind(startOfNamedTypeSpecifier); - named_type_specifier = 0; - // pop the named type specifier from the decl-specifier-seq - SpecifierAST **spec_ptr = &decl_specifier_seq; - for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) { - if (! (*spec_ptr)->next) { - *spec_ptr = 0; - break; + + if (LA() != T_SEMICOLON) { + const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier); + if (! parseInitDeclarator(declarator, acceptStructDeclarator) && maybeCtor) { + rewind(startOfNamedTypeSpecifier); + named_type_specifier = 0; + // pop the named type specifier from the decl-specifier-seq + SpecifierListAST **spec_ptr = &decl_specifier_seq; + for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) { + if (! (*spec_ptr)->next) { + *spec_ptr = 0; + break; + } } + if (! parseInitDeclarator(declarator, acceptStructDeclarator)) + return false; } - if (! parseInitDeclarator(declarator, acceptStructDeclarator)) - return false; } // if there is no valid declarator @@ -2861,37 +3143,59 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, if (declarator) { *declarator_ptr = new (_pool) DeclaratorListAST; - (*declarator_ptr)->declarator = declarator; + (*declarator_ptr)->value = declarator; declarator_ptr = &(*declarator_ptr)->next; } if (LA() == T_COMMA || LA() == T_SEMICOLON || has_complex_type_specifier) { while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA + declarator = 0; if (parseInitDeclarator(declarator, acceptStructDeclarator)) { *declarator_ptr = new (_pool) DeclaratorListAST; - (*declarator_ptr)->comma_token = comma_token; - (*declarator_ptr)->declarator = declarator; + (*declarator_ptr)->value = declarator; declarator_ptr = &(*declarator_ptr)->next; } } SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; - ast->declarators = declarator_list; +#ifdef ICHECK_BUILD + ast->invoke_token = invoke_token; +#endif + ast->decl_specifier_list = decl_specifier_seq; + ast->declarator_list = declarator_list; match(T_SEMICOLON, &ast->semicolon_token); node = ast; return true; } else if (! _inFunctionBody && declarator && (LA() == T_COLON || LA() == T_LBRACE || LA() == T_TRY)) { CtorInitializerAST *ctor_initializer = 0; - if (LA() == T_COLON) + bool hasCtorInitializer = false; + if (LA() == T_COLON) { + hasCtorInitializer = true; parseCtorInitializer(ctor_initializer); - if (LA() == T_LBRACE) { + if (LA() != T_LBRACE) { + const unsigned pos = cursor(); + + for (int n = 0; n < 3 && LA(); consumeToken(), ++n) + if (LA() == T_LBRACE) + break; + + if (LA() != T_LBRACE) { + _translationUnit->error(pos, "unexpected token `%s'", _translationUnit->spell(pos)); + rewind(pos); + } + } + } + + if (LA() == T_LBRACE || hasCtorInitializer) { FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; +#ifdef ICHECK_BUILD + ast->invoke_token = invoke_token; +#endif + ast->decl_specifier_list = decl_specifier_seq; ast->declarator = firstDeclarator; ast->ctor_initializer = ctor_initializer; parseFunctionBody(ast->function_body); @@ -2900,7 +3204,10 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, } else if (LA() == T_TRY) { FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST; ast->qt_invokable_token = qt_invokable_token; - ast->decl_specifier_seq = decl_specifier_seq; +#ifdef ICHECK_BUILD + ast->invoke_token = invoke_token; +#endif + ast->decl_specifier_list = decl_specifier_seq; ast->declarator = firstDeclarator; ast->ctor_initializer = ctor_initializer; parseTryBlockStatement(ast->function_body); @@ -2913,14 +3220,26 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node, return false; } -bool Parser::maybeForwardOrClassDeclaration(SpecifierAST *decl_specifier_seq) const +bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const { // look at the decl_specifier for possible fwd or class declarations. - if (SpecifierAST *spec = decl_specifier_seq) { - if (! spec->next && (spec->asElaboratedTypeSpecifier() || - spec->asEnumSpecifier() || - spec->asClassSpecifier())) - return true; + if (SpecifierListAST *it = decl_specifier_seq) { + while (it) { + SimpleSpecifierAST *spec = it->value->asSimpleSpecifier(); + if (spec && _translationUnit->tokenKind(spec->specifier_token) == T_FRIEND) + it = it->next; + else + break; + } + + if (it) { + SpecifierAST *spec = it->value; + + if (! it->next && (spec->asElaboratedTypeSpecifier() || + spec->asEnumSpecifier() || + spec->asClassSpecifier())) + return true; + } } return false; @@ -2956,7 +3275,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) TryBlockStatementAST *ast = new (_pool) TryBlockStatementAST; ast->try_token = consumeToken(); parseCompoundStatement(ast->statement); - CatchClauseAST **catch_clause_ptr = &ast->catch_clause_seq; + CatchClauseListAST **catch_clause_ptr = &ast->catch_clause_list; while (parseCatchClause(*catch_clause_ptr)) catch_clause_ptr = &(*catch_clause_ptr)->next; node = ast; @@ -2965,7 +3284,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) return false; } -bool Parser::parseCatchClause(CatchClauseAST *&node) +bool Parser::parseCatchClause(CatchClauseListAST *&node) { DEBUG_THIS_RULE(); if (LA() == T_CATCH) { @@ -2975,7 +3294,7 @@ bool Parser::parseCatchClause(CatchClauseAST *&node) parseExceptionDeclaration(ast->exception_declaration); match(T_RPAREN, &ast->rparen_token); parseCompoundStatement(ast->statement); - node = ast; + node = new (_pool) CatchClauseListAST(ast); return true; } return false; @@ -2991,10 +3310,10 @@ bool Parser::parseExceptionDeclaration(ExceptionDeclarationAST *&node) return true; } - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; if (parseTypeSpecifier(type_specifier)) { ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; parseDeclaratorOrAbstractDeclarator(ast->declarator); node = ast; return true; @@ -3191,17 +3510,17 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&node) ObjCSelectorWithArgumentsAST *args = new (_pool) ObjCSelectorWithArgumentsAST; ast->selector = args; ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST; - args->selector_arguments = last; - last->argument = new (_pool) ObjCSelectorArgumentAST; - last->argument->name_token = identifier_token; - last->argument->colon_token = consumeToken(); + args->selector_argument_list = last; + last->value = new (_pool) ObjCSelectorArgumentAST; + last->value->name_token = identifier_token; + last->value->colon_token = consumeToken(); while (LA() != T_RPAREN) { last->next = new (_pool) ObjCSelectorArgumentListAST; last = last->next; - last->argument = new (_pool) ObjCSelectorArgumentAST; - match(T_IDENTIFIER, &(last->argument->name_token)); - match(T_COLON, &(last->argument->colon_token)); + last->value = new (_pool) ObjCSelectorArgumentAST; + match(T_IDENTIFIER, &(last->value->name_token)); + match(T_COLON, &(last->value->colon_token)); } } else { ObjCSelectorWithoutArgumentsAST *args = new (_pool) ObjCSelectorWithoutArgumentsAST; @@ -3265,26 +3584,26 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg if (parseObjCSelectorArg(selectorArgument, messageArgument)) { ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST; - selAst->argument = selectorArgument; + selAst->value = selectorArgument; ObjCSelectorArgumentListAST *lastSelector = selAst; ObjCMessageArgumentListAST *argAst = new (_pool) ObjCMessageArgumentListAST; - argAst->arg = messageArgument; + argAst->value = messageArgument; ObjCMessageArgumentListAST *lastArgument = argAst; while (parseObjCSelectorArg(selectorArgument, messageArgument)) { // accept the selector args. lastSelector->next = new (_pool) ObjCSelectorArgumentListAST; lastSelector = lastSelector->next; - lastSelector->argument = selectorArgument; + lastSelector->value = selectorArgument; lastArgument->next = new (_pool) ObjCMessageArgumentListAST; lastArgument = lastArgument->next; - lastArgument->arg = messageArgument; + lastArgument->value = messageArgument; } if (LA() == T_COMMA) { - ExpressionAST **lastExpression = &(lastArgument->arg->parameter_value_expression); + ExpressionAST **lastExpression = &(lastArgument->value->parameter_value_expression); while (LA() == T_COMMA) { BinaryExpressionAST *binaryExpression = new (_pool) BinaryExpressionAST; @@ -3296,7 +3615,7 @@ bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArg } ObjCSelectorWithArgumentsAST *selWithArgs = new (_pool) ObjCSelectorWithArgumentsAST; - selWithArgs->selector_arguments = selAst; + selWithArgs->selector_argument_list = selAst; selNode = selWithArgs; argNode = argAst; @@ -3331,29 +3650,16 @@ bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessage selNode->colon_token = consumeToken(); argNode = new (_pool) ObjCMessageArgumentAST; - ExpressionAST *expr = argNode->parameter_value_expression; + ExpressionAST **expr = &(argNode->parameter_value_expression); unsigned expressionStart = cursor(); - if (parseAssignmentExpression(expr) && LA() == T_COLON && expr->asCastExpression()) { + if (parseAssignmentExpression(*expr) && LA() == T_COLON && (*expr)->asCastExpression()) { rewind(expressionStart); - parseUnaryExpression(expr); + parseUnaryExpression(*expr); + // } return true; } -bool Parser::parseObjCMethodSignature() -{ - DEBUG_THIS_RULE(); - unsigned selector_token = 0; - if (parseObjCSelector(selector_token)) { - while (LA() == T_COMMA) { - consumeToken(); // skip T_COMMA - parseObjCSelector(selector_token); - } - return true; - } - return false; -} - bool Parser::parseNameId(NameAST *&name) { DEBUG_THIS_RULE(); @@ -3361,6 +3667,9 @@ bool Parser::parseNameId(NameAST *&name) if (! parseName(name)) return false; + if (LA() == T_RPAREN || LA() == T_COMMA) + return true; + QualifiedNameAST *qualified_name_id = name->asQualifiedName(); TemplateIdAST *template_id = 0; @@ -3376,9 +3685,9 @@ bool Parser::parseNameId(NameAST *&name) else if (LA() == T_LPAREN) { // a template-id followed by a T_LPAREN - if (TemplateArgumentListAST *template_arguments = template_id->template_arguments) { - if (! template_arguments->next && template_arguments->template_argument && - template_arguments->template_argument->asBinaryExpression()) { + if (TemplateArgumentListAST *template_arguments = template_id->template_argument_list) { + if (! template_arguments->next && template_arguments->value && + template_arguments->value->asBinaryExpression()) { unsigned saved = cursor(); ExpressionAST *expr = 0; @@ -3545,7 +3854,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) default: { unsigned start = cursor(); - SpecifierAST *type_specifier = 0; + SpecifierListAST *type_specifier = 0; bool blocked = blockErrors(true); if (lookAtBuiltinTypeSpecifier() && parseSimpleTypeSpecifier(type_specifier) && @@ -3556,7 +3865,7 @@ bool Parser::parseCorePostfixExpression(ExpressionAST *&node) if (LA() == T_RPAREN) { unsigned rparen_token = consumeToken(); TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST; - ast->type_specifier = type_specifier; + ast->type_specifier_list = type_specifier; ast->lparen_token = lparen_token; ast->expression_list = expression_list; ast->rparen_token = rparen_token; @@ -3598,7 +3907,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) { DEBUG_THIS_RULE(); if (parseCorePostfixExpression(node)) { - PostfixAST *postfix_expressions = 0, + PostfixListAST *postfix_expressions = 0, **postfix_ptr = &postfix_expressions; while (LA()) { if (LA() == T_LPAREN) { @@ -3606,19 +3915,19 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) ast->lparen_token = consumeToken(); parseExpressionList(ast->expression_list); match(T_RPAREN, &ast->rparen_token); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_LBRACKET) { ArrayAccessAST *ast = new (_pool) ArrayAccessAST; ast->lbracket_token = consumeToken(); parseExpression(ast->expression); match(T_RBRACKET, &ast->rbracket_token); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) { PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST; ast->incr_decr_token = consumeToken(); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else if (LA() == T_DOT || LA() == T_ARROW) { MemberAccessAST *ast = new (_pool) MemberAccessAST; @@ -3628,7 +3937,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) if (! parseNameId(ast->member_name)) _translationUnit->error(cursor(), "expected unqualified-id before token `%s'", tok().spell()); - *postfix_ptr = ast; + *postfix_ptr = new (_pool) PostfixListAST(ast); postfix_ptr = &(*postfix_ptr)->next; } else break; } // while @@ -3636,7 +3945,7 @@ bool Parser::parsePostfixExpression(ExpressionAST *&node) if (postfix_expressions) { PostfixExpressionAST *ast = new (_pool) PostfixExpressionAST; ast->base_expression = node; - ast->postfix_expressions = postfix_expressions; + ast->postfix_expression_list = postfix_expressions; node = ast; } return true; @@ -3655,9 +3964,13 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node) case T_PLUS: case T_MINUS: case T_EXCLAIM: { + unsigned op = cursor(); UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST; ast->unary_op_token = consumeToken(); - parseCastExpression(ast->expression); + if (! parseCastExpression(ast->expression)) { + _translationUnit->error(op, "expected expression after token `%s'", + _translationUnit->spell(op)); + } node = ast; return true; } @@ -3800,24 +4113,27 @@ bool Parser::parseNewExpression(ExpressionAST *&node) bool Parser::parseNewTypeId(NewTypeIdAST *&node) { DEBUG_THIS_RULE(); - SpecifierAST *typeSpec = 0; + SpecifierListAST *typeSpec = 0; if (! parseTypeSpecifier(typeSpec)) return false; NewTypeIdAST *ast = new (_pool) NewTypeIdAST; - ast->type_specifier = typeSpec; - PtrOperatorAST **ptrop_it = &ast->ptr_operators; + ast->type_specifier_list = typeSpec; + + PtrOperatorListAST **ptrop_it = &ast->ptr_operator_list; while (parsePtrOperator(*ptrop_it)) ptrop_it = &(*ptrop_it)->next; - NewArrayDeclaratorAST **it = &ast->new_array_declarators; + + NewArrayDeclaratorListAST **it = &ast->new_array_declarator_list; while (parseNewArrayDeclarator(*it)) it = &(*it)->next; + node = ast; return true; } -bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node) +bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node) { DEBUG_THIS_RULE(); if (LA() != T_LBRACKET) @@ -3827,7 +4143,9 @@ bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node) ast->lbracket_token = consumeToken(); parseExpression(ast->expression); match(T_RBRACKET, &ast->rbracket_token); - node = ast; + + node = new (_pool) NewArrayDeclaratorListAST; + node->value = ast; return true; } @@ -3898,247 +4216,57 @@ bool Parser::parseCastExpression(ExpressionAST *&node) bool Parser::parsePmExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseCastExpression(node)) - return false; - - while (LA() == T_ARROW_STAR || LA() == T_DOT_STAR) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseCastExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_ARROW_STAR, _templateArguments)) } bool Parser::parseMultiplicativeExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parsePmExpression(node)) - return false; - - while (LA() == T_STAR || LA() == T_SLASH || LA() == T_PERCENT) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parsePmExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_STAR, _templateArguments)) } bool Parser::parseAdditiveExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseMultiplicativeExpression(node)) - return false; - - while (LA() == T_PLUS || LA() == T_MINUS) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseMultiplicativeExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_PLUS, _templateArguments)) } bool Parser::parseShiftExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseAdditiveExpression(node)) - return false; - - while (LA() == T_LESS_LESS || LA() == T_GREATER_GREATER) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseAdditiveExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_LESS_LESS, _templateArguments)) } bool Parser::parseRelationalExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseShiftExpression(node)) - return false; - - while (LA() == T_LESS || (LA() == T_GREATER && ! _templateArguments) || - LA() == T_LESS_EQUAL || LA() == T_GREATER_EQUAL) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseShiftExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_LESS, _templateArguments)) } bool Parser::parseEqualityExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseRelationalExpression(node)) - return false; - - while (LA() == T_EQUAL_EQUAL || LA() == T_EXCLAIM_EQUAL) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseRelationalExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_EQUAL_EQUAL, _templateArguments)) } bool Parser::parseAndExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseEqualityExpression(node)) - return false; - - while (LA() == T_AMPER) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseEqualityExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_AMPER, _templateArguments)) } bool Parser::parseExclusiveOrExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseAndExpression(node)) - return false; - - while (LA() == T_CARET) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseAndExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_CARET, _templateArguments)) } bool Parser::parseInclusiveOrExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseExclusiveOrExpression(node)) - return false; - - while (LA() == T_PIPE) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseExclusiveOrExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_PIPE, _templateArguments)) } bool Parser::parseLogicalAndExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseInclusiveOrExpression(node)) - return false; - - while (LA() == T_AMPER_AMPER) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseInclusiveOrExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_AMPER_AMPER, _templateArguments)) } bool Parser::parseLogicalOrExpression(ExpressionAST *&node) { - DEBUG_THIS_RULE(); - if (! parseLogicalAndExpression(node)) - return false; - - while (LA() == T_PIPE_PIPE) { - unsigned op = consumeToken(); - - ExpressionAST *rightExpr = 0; - if (! parseLogicalAndExpression(rightExpr)) - return false; - - BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; - ast->binary_op_token = op; - ast->left_expression = node; - ast->right_expression = rightExpr; - node = ast; - } - - return true; + PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, precedence(T_PIPE_PIPE, _templateArguments)) } bool Parser::parseConditionalExpression(ExpressionAST *&node) @@ -4193,8 +4321,11 @@ bool Parser::parseAssignmentExpression(ExpressionAST *&node) unsigned op = consumeToken(); ExpressionAST *rightExpr = 0; - if (! parseAssignmentExpression(rightExpr)) + if (! parseAssignmentExpression(rightExpr)) { + _translationUnit->error(op, "expected expression after token `%s'", + _translationUnit->spell(op)); return false; + } BinaryExpressionAST *ast = new (_pool) BinaryExpressionAST; ast->binary_op_token = op; @@ -4232,7 +4363,39 @@ bool Parser::parseConstantExpression(ExpressionAST *&node) bool Parser::parseExpression(ExpressionAST *&node) { DEBUG_THIS_RULE(); - return parseCommaExpression(node); + + if (_expressionDepth > MAX_EXPRESSION_DEPTH) + return false; + + ++_expressionDepth; + bool success = parseCommaExpression(node); + --_expressionDepth; + return success; +} + +void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence) +{ + DEBUG_THIS_RULE(); + + while (precedence(tok().kind(), _templateArguments) >= minPrecedence) { + const int operPrecedence = precedence(tok().kind(), _templateArguments); + const int oper = consumeToken(); + ExpressionAST *rhs = 0; + if (!parseCastExpression(rhs)) + return; + + for (int tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments); + precedenceAhead > operPrecedence && isBinaryOperator(tokenKindAhead); + tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments)) { + parseExpressionWithOperatorPrecedence(rhs, precedenceAhead); + } + + BinaryExpressionAST *expr = new (_pool) BinaryExpressionAST; + expr->left_expression = lhs; + expr->binary_op_token = oper; + expr->right_expression = rhs; + lhs = expr; + } } bool Parser::parseCommaExpression(ExpressionAST *&node) @@ -4309,21 +4472,20 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node) unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4348,11 +4510,11 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node) // T_AT_END // bool Parser::parseObjCInterface(DeclarationAST *&node, - SpecifierAST *attributes) + SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (! attributes && LA() == T___ATTRIBUTE__) { - SpecifierAST **attr = &attributes; + SpecifierListAST **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; } @@ -4372,7 +4534,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, "invalid attributes for category interface declaration"); ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->interface_token = objc_interface_token; SimpleNameAST *class_name = new (_pool) SimpleNameAST; class_name->identifier_token= identifier_token; @@ -4389,11 +4551,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4404,7 +4566,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, } else { // a class interface declaration ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->interface_token = objc_interface_token; SimpleNameAST* class_name = new (_pool) SimpleNameAST; class_name->identifier_token = identifier_token; @@ -4420,11 +4582,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); parseObjClassInstanceVariables(ast->inst_vars_decl); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4438,11 +4600,11 @@ bool Parser::parseObjCInterface(DeclarationAST *&node, // objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON // bool Parser::parseObjCProtocol(DeclarationAST *&node, - SpecifierAST *attributes) + SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (! attributes && LA() == T___ATTRIBUTE__) { - SpecifierAST **attr = &attributes; + SpecifierListAST **attr = &attributes; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; } @@ -4458,23 +4620,22 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, // a protocol forward declaration ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->protocol_token = protocol_token; - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4484,7 +4645,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, } else { // a protocol definition ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->protocol_token = protocol_token; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; @@ -4492,11 +4653,11 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node, parseObjCProtocolRefs(ast->protocol_refs); - DeclarationListAST **nextMembers = &(ast->member_declarations); + DeclarationListAST **nextMembers = &(ast->member_declaration_list); DeclarationAST *declaration = 0; while (parseObjCInterfaceMemberDeclaration(declaration)) { *nextMembers = new (_pool) DeclarationListAST; - (*nextMembers)->declaration = declaration; + (*nextMembers)->value = declaration; nextMembers = &((*nextMembers)->next); } @@ -4535,7 +4696,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node) ast->category_name = category_name; match(T_RPAREN, &(ast->rparen_token)); - parseObjCMethodDefinitionList(ast->member_declarations); + parseObjCMethodDefinitionList(ast->member_declaration_list); match(T_AT_END, &(ast->end_token)); node = ast; @@ -4555,7 +4716,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node) } parseObjClassInstanceVariables(ast->inst_vars_decl); - parseObjCMethodDefinitionList(ast->member_declarations); + parseObjCMethodDefinitionList(ast->member_declaration_list); match(T_AT_END, &(ast->end_token)); node = ast; @@ -4590,28 +4751,29 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST; ast->synthesized_token = consumeToken(); ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST; - ast->property_identifiers = last; - last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST; - match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); + ast->property_identifier_list = last; + last->value = new (_pool) ObjCSynthesizedPropertyAST; + match(T_IDENTIFIER, &(last->value->property_identifier)); if (LA() == T_EQUAL) { - last->synthesized_property->equals_token = consumeToken(); + last->value->equals_token = consumeToken(); - match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); + match(T_IDENTIFIER, &(last->value->property_alias_identifier)); } while (LA() == T_COMMA) { - last->comma_token = consumeToken(); + consumeToken(); // consume T_COMMA + last->next = new (_pool) ObjCSynthesizedPropertyListAST; last = last->next; - last->synthesized_property = new (_pool) ObjCSynthesizedPropertyAST; - match(T_IDENTIFIER, &(last->synthesized_property->property_identifier)); + last->value = new (_pool) ObjCSynthesizedPropertyAST; + match(T_IDENTIFIER, &(last->value->property_identifier)); if (LA() == T_EQUAL) { - last->synthesized_property->equals_token = consumeToken(); + last->value->equals_token = consumeToken(); - match(T_IDENTIFIER, &(last->synthesized_property->property_alias_identifier)); + match(T_IDENTIFIER, &(last->value->property_alias_identifier)); } } @@ -4624,19 +4786,20 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) case T_AT_DYNAMIC: { ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST; ast->dynamic_token = consumeToken(); - ast->property_identifiers = new (_pool) IdentifierListAST; + ast->property_identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; match(T_IDENTIFIER, &(name->identifier_token)); - ast->property_identifiers->name = name; + ast->property_identifier_list->value = name; - IdentifierListAST *last = ast->property_identifiers; + ObjCIdentifierListAST *last = ast->property_identifier_list; while (LA() == T_COMMA) { - last->comma_token = consumeToken(); - last->next = new (_pool) IdentifierListAST; + consumeToken(); // consume T_COMMA + + last->next = new (_pool) ObjCIdentifierListAST; last = last->next; name = new (_pool) SimpleNameAST; - match(T_IDENTIFIER, &(name->identifier_token)); - last->name = name; + match(T_IDENTIFIER, &name->identifier_token); + last->value = name; } match(T_SEMICOLON, &(ast->semicolon_token)); @@ -4662,7 +4825,7 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node) if (declaration) { *next = new (_pool) DeclarationListAST; - (*next)->declaration = declaration; + (*next)->value = declaration; next = &((*next)->next); } } @@ -4708,21 +4871,20 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node) unsigned identifier_token = 0; match(T_IDENTIFIER, &identifier_token); - ast->identifier_list = new (_pool) IdentifierListAST; + ast->identifier_list = new (_pool) ObjCIdentifierListAST; SimpleNameAST *name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - ast->identifier_list->name = name; - IdentifierListAST **nextId = &(ast->identifier_list->next); + ast->identifier_list->value = name; + ObjCIdentifierListAST **nextId = &(ast->identifier_list->next); while (LA() == T_COMMA) { - unsigned comma_token = consumeToken(); + consumeToken(); // consume T_COMMA match(T_IDENTIFIER, &identifier_token); - *nextId = new (_pool) IdentifierListAST; - (*nextId)->comma_token = comma_token; + *nextId = new (_pool) ObjCIdentifierListAST; name = new (_pool) SimpleNameAST; name->identifier_token = identifier_token; - (*nextId)->name = name; + (*nextId)->value = name; nextId = &((*nextId)->next); } @@ -4744,14 +4906,14 @@ bool Parser::parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST ObjCInstanceVariablesDeclarationAST *ast = new (_pool) ObjCInstanceVariablesDeclarationAST; match(T_LBRACE, &(ast->lbrace_token)); - for (DeclarationListAST **next = &(ast->instance_variables); LA(); next = &((*next)->next)) { + for (DeclarationListAST **next = &(ast->instance_variable_list); LA(); next = &((*next)->next)) { if (LA() == T_RBRACE) break; const unsigned start = cursor(); *next = new (_pool) DeclarationListAST; - parseObjCInstanceVariableDeclaration((*next)->declaration); + parseObjCInstanceVariableDeclaration((*next)->value); if (start == cursor()) { // skip stray token. @@ -4842,14 +5004,14 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node) // objc-property-declaration ::= // T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration // -bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *attributes) +bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes) { DEBUG_THIS_RULE(); if (LA() != T_AT_PROPERTY) return false; ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST; - ast->attributes = attributes; + ast->attribute_list = attributes; ast->property_token = consumeToken(); if (LA() == T_LPAREN) { @@ -4857,19 +5019,17 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a ObjCPropertyAttributeAST *property_attribute = 0; if (parseObjCPropertyAttribute(property_attribute)) { - ast->property_attributes = new (_pool) ObjCPropertyAttributeListAST; - ast->property_attributes->attr = property_attribute; - ObjCPropertyAttributeListAST *last = ast->property_attributes; + ast->property_attribute_list = new (_pool) ObjCPropertyAttributeListAST; + ast->property_attribute_list->value = property_attribute; + ObjCPropertyAttributeListAST *last = ast->property_attribute_list; while (LA() == T_COMMA) { - last->comma_token = consumeToken(); + consumeToken(); // consume T_COMMA last->next = new (_pool) ObjCPropertyAttributeListAST; last = last->next; - if (!parseObjCPropertyAttribute(last->attr)) { + if (!parseObjCPropertyAttribute(last->value)) { _translationUnit->error(_tokenIndex, "expected token `%s' got `%s'", Token::name(T_IDENTIFIER), tok().spell()); - while (LA() != T_RPAREN) - consumeToken(); break; } } @@ -4878,9 +5038,11 @@ bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierAST *a match(T_RPAREN, &(ast->rparen_token)); } - parseSimpleDeclaration(ast->simple_declaration, /*accept-struct-declarators = */ true); + if (parseSimpleDeclaration(ast->simple_declaration, /*accept-struct-declarators = */ true)) + node = ast; + else + _translationUnit->error(_tokenIndex, "expected a simple declaration"); - node = ast; return true; } @@ -4908,21 +5070,21 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) ObjCSelectorWithArgumentsAST *sel = new (_pool) ObjCSelectorWithArgumentsAST; ast->selector = sel; ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST; - sel->selector_arguments = lastSel; - sel->selector_arguments->argument = argument; + sel->selector_argument_list = lastSel; + sel->selector_argument_list->value = argument; - ast->arguments = new (_pool) ObjCMessageArgumentDeclarationListAST; - ast->arguments->argument_declaration = declaration; - ObjCMessageArgumentDeclarationListAST *lastArg = ast->arguments; + ast->argument_list = new (_pool) ObjCMessageArgumentDeclarationListAST; + ast->argument_list->value = declaration; + ObjCMessageArgumentDeclarationListAST *lastArg = ast->argument_list; while (parseObjCKeywordDeclaration(argument, declaration)) { lastSel->next = new (_pool) ObjCSelectorArgumentListAST; lastSel = lastSel->next; - lastSel->argument = argument; + lastSel->value = argument; lastArg->next = new (_pool) ObjCMessageArgumentDeclarationListAST; lastArg = lastArg->next; - lastArg->argument_declaration = declaration; + lastArg->value = declaration; } while (LA() == T_COMMA) { @@ -4945,7 +5107,7 @@ bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node) _translationUnit->error(cursor(), "expected a selector"); } - SpecifierAST **attr = &(ast->attributes); + SpecifierListAST **attr = &ast->attribute_list; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; @@ -4969,7 +5131,7 @@ bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node) node = new (_pool) ObjCPropertyAttributeAST; - Identifier *id = tok().identifier; + const Identifier *id = tok().identifier; const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); switch (k) { case Token_copy: @@ -4994,10 +5156,10 @@ bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node) node->attribute_identifier_token = consumeToken(); match(T_EQUAL, &(node->equals_token)); ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST; - selector->selector_arguments = new (_pool) ObjCSelectorArgumentListAST; - selector->selector_arguments->argument = new (_pool) ObjCSelectorArgumentAST; - match(T_IDENTIFIER, &(selector->selector_arguments->argument->name_token)); - match(T_COLON, &(selector->selector_arguments->argument->colon_token)); + selector->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST; + selector->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST; + match(T_IDENTIFIER, &(selector->selector_argument_list->value->name_token)); + match(T_COLON, &(selector->selector_argument_list->value->colon_token)); node->method_selector = selector; return true; } @@ -5052,7 +5214,7 @@ bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, Obj parseObjCTypeName(node->type_name); - SpecifierAST **attr = &(node->attributes); + SpecifierListAST **attr = &node->attribute_list; while (parseAttributeSpecifier(*attr)) attr = &(*attr)->next; @@ -5067,7 +5229,7 @@ bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier) if (LA() != T_IDENTIFIER) return false; - Identifier *id = tok().identifier; + const Identifier *id = tok().identifier; const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); if (k == Token_identifier) return false; @@ -5080,7 +5242,7 @@ bool Parser::peekAtObjCContextKeyword(int kind) if (LA() != T_IDENTIFIER) return false; - Identifier *id = tok().identifier; + const Identifier *id = tok().identifier; const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); return k == kind; } |