diff --git a/generator/parser/parser.cpp b/generator/parser/parser.cpp index 9ffde3f00..f07b47ca4 100644 --- a/generator/parser/parser.cpp +++ b/generator/parser/parser.cpp @@ -52,10 +52,32 @@ #include #include +#define STRINGIZE(x) STRINGIZE2(x) +#define STRINGIZE2(x) #x + +#if defined(_MSC_VER) +#define PARSER_METHOD_NAME __FUNCTION__ ":" STRINGIZE(__LINE__) +#elif defined(__GNUC__) +#include +// on gcc __FUNCTION__ is a variable, not a string constant +// - solution found here: https://stackoverflow.com/a/61546848 +#define PARSER_METHOD_NAME \ + [](const char* fn, int ln) { \ + std::stringstream ss; \ + ss << fn << ":" << ln; \ + return ss.str(); \ + }(__FUNCTION__, __LINE__).c_str() +#else +#define PARSER_METHOD_NAME "" +#endif + + +#define SYNTAX_ERROR() syntaxError(PARSER_METHOD_NAME) + #define ADVANCE(tk, descr) \ { \ if (token_stream.lookAhead() != tk) { \ - tokenRequiredError(tk); \ + tokenRequiredError(tk, PARSER_METHOD_NAME); \ return false; \ } \ nextToken(); \ @@ -64,7 +86,7 @@ #define ADVANCE_NR(tk, descr) \ do { \ if (token_stream.lookAhead() != tk) { \ - tokenRequiredError(tk); \ + tokenRequiredError(tk, PARSER_METHOD_NAME); \ } \ else \ nextToken(); \ @@ -165,7 +187,7 @@ bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node) return true; } -void Parser::tokenRequiredError(int token) +void Parser::tokenRequiredError(int token, const char* functionName) { QString err; @@ -176,11 +198,10 @@ void Parser::tokenRequiredError(int token) err += token_name(token_stream.lookAhead()); err += "''"; - - reportError(err); + reportError(err, functionName); } -void Parser::syntaxError() +void Parser::syntaxError(const char* functionName) { QString err; @@ -189,10 +210,10 @@ void Parser::syntaxError() err += token_name(token_stream.lookAhead()); err += "''"; - reportError(err); + reportError(err, functionName); } -void Parser::reportError(const QString& msg) +void Parser::reportError(const QString& msg, const char* functionName) { if (!_M_block_errors) { @@ -208,6 +229,10 @@ void Parser::reportError(const QString& msg) errmsg.setColumn(column); errmsg.setFileName(fileName); errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg); + if (functionName && *functionName) { + errmsg.setMessage(errmsg.message() + " in " + functionName); + } + control->reportError(errmsg); } } @@ -852,7 +877,7 @@ bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node) if (!parseSimpleTypeSpecifier(ast->type_specifier)) { - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -886,7 +911,7 @@ bool Parser::parseTemplateArgumentList(const ListNode *&no { if (reportError) { - syntaxError(); + SYNTAX_ERROR(); break; } @@ -1642,7 +1667,7 @@ bool Parser::parseTemplateParameterList(const ListNode *& if (!parseTemplateParameter(param)) { - syntaxError(); + SYNTAX_ERROR(); break; } else @@ -1721,7 +1746,7 @@ bool Parser::parseTypeParameter(TypeParameterAST *&node) if(!parseTypeId(ast->type_id)) { - //syntaxError(); + //SYNTAX_ERROR(); rewind(start); return false; } @@ -1758,7 +1783,7 @@ bool Parser::parseTypeParameter(TypeParameterAST *&node) if (!parseTypeId(ast->type_id)) { - syntaxError(); + SYNTAX_ERROR(); return false; } } @@ -1857,7 +1882,7 @@ bool Parser::parseInitDeclaratorList(const ListNode *&node) if (!parseInitDeclarator(decl)) { - syntaxError(); + SYNTAX_ERROR(); break; } node = snoc(node, decl, _M_pool); @@ -2933,7 +2958,7 @@ bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node) block_errors(blocked); if (!node) - syntaxError(); + SYNTAX_ERROR(); return node != 0; } @@ -3203,7 +3228,7 @@ bool Parser::parseSwitchStatement(StatementAST *&node) StatementAST *stmt = 0; if (!parseCompoundStatement(stmt)) { - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -3490,7 +3515,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) const ListNode *declarators = 0; if (!parseInitDeclaratorList(declarators)) { - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -3534,7 +3559,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) rewind(startDeclarator); if (!parseInitDeclaratorList(declarators)) { - syntaxError(); + SYNTAX_ERROR(); return false; } } @@ -3546,7 +3571,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) TypeSpecifierAST* trailingReturnTypeSpec = 0; if (!parseTypeSpecifier(trailingReturnTypeSpec)) { // todo: replace "auto" return type? But I doubt we can handle these return types anyway. - syntaxError(); + SYNTAX_ERROR(); return false; } maybeFunctionDefinition = true; @@ -3575,7 +3600,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) { if (!maybeFunctionDefinition) { - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -3602,7 +3627,7 @@ bool Parser::parseDeclarationInternal(DeclarationAST *&node) } // end switch } - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -3670,7 +3695,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) StatementAST *stmt = 0; if (!parseCompoundStatement(stmt)) { - syntaxError(); + SYNTAX_ERROR(); return false; } @@ -3699,7 +3724,7 @@ bool Parser::parseTryBlockStatement(StatementAST *&node) StatementAST *body = 0; if (!parseCompoundStatement(body)) { - syntaxError(); + SYNTAX_ERROR(); return false; } } @@ -3758,6 +3783,8 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node) CHECK('}'); break; + // case '[': // TODO: parse lambda expression + default: if (!parseName(ast->name, true)) // this can also be a template return false; diff --git a/generator/parser/parser.h b/generator/parser/parser.h index fdec18dcd..4843ff7cb 100644 --- a/generator/parser/parser.h +++ b/generator/parser/parser.h @@ -62,9 +62,9 @@ class Parser TranslationUnitAST *parse(const char *contents, std::size_t size, pool *p); private: - void reportError(const QString& msg); - void syntaxError(); - void tokenRequiredError(int expected); + void reportError(const QString& msg, const char* functionName = nullptr); + void syntaxError(const char* functionName = nullptr); + void tokenRequiredError(int expected, const char* functionName = nullptr); public: bool skipFunctionBody(StatementAST *&node);