diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 3d710db3669add45c8fafe9f0bcbf58288f2a0b2..d0ac090099d1195dba22fccac722e2b63789cb24 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -611,8 +611,7 @@ AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const { AsmDefinitionAST *ast = new (pool) AsmDefinitionAST; ast->asm_token = asm_token; - if (cv_qualifier_seq) - ast->cv_qualifier_seq = cv_qualifier_seq->clone(pool); + ast->volatile_token = volatile_token; ast->lparen_token = lparen_token; ast->rparen_token = rparen_token; ast->semicolon_token = semicolon_token; @@ -622,9 +621,7 @@ AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const void AsmDefinitionAST::accept0(ASTVisitor *visitor) { if (visitor->visit(this)) { - for (SpecifierAST *spec = cv_qualifier_seq; spec; - spec = spec->next) - accept(spec, visitor); + // ### accept the asm operand list. } } @@ -641,11 +638,8 @@ unsigned AsmDefinitionAST::lastToken() const return rparen_token + 1; else if (lparen_token) return lparen_token + 1; - for (SpecifierAST *it = cv_qualifier_seq; it; it = it->next) { - if (! it->next) - return it->lastToken(); - } - + else if (volatile_token) + return volatile_token + 1; return asm_token + 1; } diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index d7f346c5b0ce78b5da0c5c4c6bad08ebcf2499a3..1918ee795350053b8f717f3d5bf4debf9001cb5c 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -397,8 +397,10 @@ class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST { public: unsigned asm_token; - SpecifierAST *cv_qualifier_seq; + unsigned volatile_token; unsigned lparen_token; + // ### string literals + // ### asm operand list unsigned rparen_token; unsigned semicolon_token; diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index 4dfbcb995a237232883e10fec6a166329da9c69e..32d9b0ac7f48ce40026194f0a1b0ea60b97cec44 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -627,22 +627,92 @@ bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node) bool Parser::parseAsmDefinition(DeclarationAST *&node) { - if (LA() == T_ASM) { - AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST; - ast->asm_token = consumeToken(); - parseCvQualifiers(ast->cv_qualifier_seq); - if (LA() == T_LPAREN) { - ast->lparen_token = cursor(); - if (skip(T_LPAREN, T_RPAREN)) - ast->rparen_token = consumeToken(); + if (LA() != T_ASM) + return false; + + AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST; + ast->asm_token = consumeToken(); + + if (LA() == T_VOLATILE) + ast->volatile_token = consumeToken(); + + match(T_LPAREN, &ast->lparen_token); + unsigned string_literal_token = 0; + match(T_STRING_LITERAL, &string_literal_token); + while (LA() == T_STRING_LITERAL) { + consumeToken(); + } + if (LA() == T_COLON) { + consumeToken(); // skip T_COLON + parseAsmOperandList(); + if (LA() == T_COLON) { + consumeToken(); + parseAsmOperandList(); + if (LA() == T_COLON) { + consumeToken(); + parseAsmClobberList(); + } + } else if (LA() == T_COLON_COLON) { + consumeToken(); + parseAsmClobberList(); + } + } else if (LA() == T_COLON_COLON) { + consumeToken(); + parseAsmClobberList(); + } + match(T_RPAREN, &ast->rparen_token); + match(T_SEMICOLON, &ast->semicolon_token); + node = ast; + return true; +} + +bool Parser::parseAsmOperandList() +{ + if (parseAsmOperand()) { + while (LA() == T_COMMA) { + consumeToken(); + parseAsmOperand(); } - match(T_SEMICOLON, &ast->semicolon_token); - node = ast; return true; } return false; } +bool Parser::parseAsmOperand() +{ + unsigned string_literal_token = 0; + match(T_STRING_LITERAL, &string_literal_token); + + if (LA() == T_LBRACKET) { + /*unsigned lbracket_token = */ consumeToken(); + match(T_STRING_LITERAL, &string_literal_token); + unsigned rbracket_token = 0; + match(T_RBRACKET, &rbracket_token); + } + + unsigned lparen_token = 0, rparen_token = 0; + match(T_LPAREN, &lparen_token); + ExpressionAST *expression = 0; + parseExpression(expression); + match(T_RPAREN, &rparen_token); + return true; +} + +bool Parser::parseAsmClobberList() +{ + if (LA() != T_STRING_LITERAL) + return false; + + unsigned string_literal_token = consumeToken(); + + while (LA() == T_COMMA) { + consumeToken(); + match(T_STRING_LITERAL, &string_literal_token); + } + + return true; +} + bool Parser::parseTemplateDeclaration(DeclarationAST *&node) { if (! (LA(1) == T_TEMPLATE || ((LA(1) == T_EXPORT || LA(1) == T_EXTERN) diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index 5f27b57b47c7676f70762afade039f44a8ad3960..38a0840cf95921c4296f8871e97967891e9badf9 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -85,6 +85,9 @@ public: bool parseAdditiveExpression(ExpressionAST *&node); bool parseAndExpression(ExpressionAST *&node); bool parseAsmDefinition(DeclarationAST *&node); + bool parseAsmOperandList(); + bool parseAsmOperand(); + bool parseAsmClobberList(); bool parseAssignmentExpression(ExpressionAST *&node); bool parseBaseClause(BaseSpecifierAST *&node); bool parseBaseSpecifier(BaseSpecifierAST *&node); diff --git a/src/shared/cplusplus/PrettyPrinter.cpp b/src/shared/cplusplus/PrettyPrinter.cpp index 6acb109dcfb41d1aa5467cee7f0ac63f1f8c1746..d6c604c3abbcec56c3b82f493df23f7f506b55ed 100644 --- a/src/shared/cplusplus/PrettyPrinter.cpp +++ b/src/shared/cplusplus/PrettyPrinter.cpp @@ -101,10 +101,8 @@ bool PrettyPrinter::visit(ArrayInitializerAST *ast) bool PrettyPrinter::visit(AsmDefinitionAST *ast) { out << spell(ast->asm_token); - for (SpecifierAST *it = ast->cv_qualifier_seq; it; it = it->next) { - out << ' '; - accept(it); - } + if (ast->volatile_token) + out << ' ' << spell(ast->volatile_token) << ' '; out << '('; out << "/* ### implement me */"; out << ");";