forked from qt-creator/qt-creator
Fixes: Parsing of GCC asm definitions.
This commit is contained in:
committed by
Roberto Raggi
parent
40eabdd008
commit
d7defc6fe0
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 << ");";
|
||||
|
||||
Reference in New Issue
Block a user