Commit b4d72a78 authored by Erik Verbruggen's avatar Erik Verbruggen

Added parser support for Q_INTERFACES.

parent 61132f26
......@@ -1421,6 +1421,8 @@ bool Preprocessor::isQtReservedWord(const QByteArray &macroId) const
return true;
else if (size == 7 && macroId.at(0) == 'Q' && macroId == "Q_FLAGS")
return true;
else if (size == 12 && macroId.at(0) == 'Q' && macroId == "Q_INTERFACES")
return true;
else if (size == 6 && macroId.at(0) == 'S' && macroId == "SIGNAL")
return true;
else if (size == 4 && macroId.at(0) == 'S' && macroId == "SLOT")
......
......@@ -197,7 +197,7 @@ unsigned QtEnumDeclarationAST::lastToken() const
unsigned QtFlagsDeclarationAST::firstToken() const
{
return flags_specifier_token + 1;
return flags_specifier_token;
}
unsigned QtFlagsDeclarationAST::lastToken() const
......@@ -212,6 +212,43 @@ unsigned QtFlagsDeclarationAST::lastToken() const
return flags_specifier_token + 1;
}
unsigned QtInterfaceNameAST::firstToken() const
{
if (interface_name)
return interface_name->firstToken();
else if (constraint_list)
return constraint_list->firstToken();
else
return 0;
}
unsigned QtInterfaceNameAST::lastToken() const
{
if (constraint_list)
return constraint_list->lastToken();
else if (interface_name)
return interface_name->lastToken();
else
return 0;
}
unsigned QtInterfacesDeclarationAST::firstToken() const
{
return interfaces_token;
}
unsigned QtInterfacesDeclarationAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
else if (interface_name_list)
return interface_name_list->lastToken();
else if (lparen_token)
return lparen_token + 1;
else
return interfaces_token + 1;
}
unsigned ArrayAccessAST::firstToken() const
{
return lbracket_token;
......
......@@ -256,6 +256,8 @@ public:
virtual PtrOperatorAST *asPtrOperator() { return 0; }
virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return 0; }
virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return 0; }
virtual QtInterfaceNameAST *asQtInterfaceName() { return 0; }
virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return 0; }
virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return 0; }
virtual QtMethodAST *asQtMethod() { return 0; }
virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return 0; }
......@@ -660,6 +662,46 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QtInterfaceNameAST: public AST
{
public:
NameAST *interface_name;
NameListAST *constraint_list;
public:
virtual QtInterfaceNameAST *asQtInterfaceName() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual QtInterfaceNameAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QtInterfacesDeclarationAST: public DeclarationAST
{
public:
unsigned interfaces_token;
unsigned lparen_token;
QtInterfaceNameListAST *interface_name_list;
unsigned rparen_token;
public:
virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual QtInterfacesDeclarationAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT AsmDefinitionAST: public DeclarationAST
{
public:
......
......@@ -204,6 +204,29 @@ QtFlagsDeclarationAST *QtFlagsDeclarationAST::clone(MemoryPool *pool) const
return ast;
}
QtInterfaceNameAST *QtInterfaceNameAST::clone(MemoryPool *pool) const
{
QtInterfaceNameAST *ast = new (pool) QtInterfaceNameAST;
if (interface_name)
ast->interface_name = interface_name->clone(pool);
for (NameListAST *iter = constraint_list, **ast_iter = &ast->constraint_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
return ast;
}
QtInterfacesDeclarationAST *QtInterfacesDeclarationAST::clone(MemoryPool *pool) const
{
QtInterfacesDeclarationAST *ast = new (pool) QtInterfacesDeclarationAST;
ast->interfaces_token = interfaces_token;
ast->lparen_token = lparen_token;
for (QtInterfaceNameListAST *iter = interface_name_list, **ast_iter = &ast->interface_name_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) QtInterfaceNameListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->rparen_token = rparen_token;
return ast;
}
AsmDefinitionAST *AsmDefinitionAST::clone(MemoryPool *pool) const
{
AsmDefinitionAST *ast = new (pool) AsmDefinitionAST;
......
......@@ -153,6 +153,22 @@ bool QtFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool QtInterfaceNameAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QtInterfaceNameAST *_other = pattern->asQtInterfaceName())
return matcher->match(this, _other);
return false;
}
bool QtInterfacesDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QtInterfacesDeclarationAST *_other = pattern->asQtInterfacesDeclaration())
return matcher->match(this, _other);
return false;
}
bool AsmDefinitionAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (AsmDefinitionAST *_other = pattern->asAsmDefinition())
......
......@@ -313,6 +313,43 @@ bool ASTMatcher::match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *patte
return true;
}
bool ASTMatcher::match(QtInterfaceNameAST *node, QtInterfaceNameAST *pattern)
{
(void) node;
(void) pattern;
if (! pattern->interface_name)
pattern->interface_name = node->interface_name;
else if (! AST::match(node->interface_name, pattern->interface_name, this))
return false;
if (! pattern->constraint_list)
pattern->constraint_list = node->constraint_list;
else if (! AST::match(node->constraint_list, pattern->constraint_list, this))
return false;
return true;
}
bool ASTMatcher::match(QtInterfacesDeclarationAST *node, QtInterfacesDeclarationAST *pattern)
{
(void) node;
(void) pattern;
pattern->interfaces_token = node->interfaces_token;
pattern->lparen_token = node->lparen_token;
if (! pattern->interface_name_list)
pattern->interface_name_list = node->interface_name_list;
else if (! AST::match(node->interface_name_list, pattern->interface_name_list, this))
return false;
pattern->rparen_token = node->rparen_token;
return true;
}
bool ASTMatcher::match(AsmDefinitionAST *node, AsmDefinitionAST *pattern)
{
(void) node;
......
......@@ -43,6 +43,8 @@ public:
virtual bool match(QtPropertyDeclarationAST *node, QtPropertyDeclarationAST *pattern);
virtual bool match(QtEnumDeclarationAST *node, QtEnumDeclarationAST *pattern);
virtual bool match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *pattern);
virtual bool match(QtInterfaceNameAST *node, QtInterfaceNameAST *pattern);
virtual bool match(QtInterfacesDeclarationAST *node, QtInterfacesDeclarationAST *pattern);
virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern);
......
......@@ -157,6 +157,23 @@ void QtFlagsDeclarationAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void QtInterfaceNameAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(interface_name, visitor);
accept(constraint_list, visitor);
}
visitor->endVisit(this);
}
void QtInterfacesDeclarationAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(interface_name_list, visitor);
}
visitor->endVisit(this);
}
void AsmDefinitionAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
......
......@@ -204,6 +204,8 @@ public:
virtual bool visit(QtMethodAST *) { return true; }
virtual bool visit(QtMemberDeclarationAST *) { return true; }
virtual bool visit(QtPropertyDeclarationItemAST *) { return true; }
virtual bool visit(QtInterfacesDeclarationAST *) { return true; }
virtual bool visit(QtInterfaceNameAST *) { return true; }
// ObjC++
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
......@@ -334,6 +336,8 @@ public:
virtual void endVisit(QtMethodAST *) { }
virtual void endVisit(QtMemberDeclarationAST *) { }
virtual void endVisit(QtPropertyDeclarationItemAST *) { }
virtual void endVisit(QtInterfacesDeclarationAST *) { }
virtual void endVisit(QtInterfaceNameAST *) { }
// ObjC++
virtual void endVisit(ObjCClassDeclarationAST *) { }
......
......@@ -163,6 +163,8 @@ class PostfixExpressionAST;
class PtrOperatorAST;
class QtEnumDeclarationAST;
class QtFlagsDeclarationAST;
class QtInterfaceNameAST;
class QtInterfacesDeclarationAST;
class QtMemberDeclarationAST;
class QtMethodAST;
class QtPropertyDeclarationAST;
......@@ -213,6 +215,7 @@ typedef List<PtrOperatorAST *> PtrOperatorListAST;
typedef List<SpecifierAST *> SpecifierListAST;
typedef List<QtPropertyDeclarationItemAST *> QtPropertyDeclarationItemListAST;
typedef List<NameAST *> NameListAST;
typedef List<QtInterfaceNameAST *> QtInterfaceNameListAST;
typedef List<ObjCMessageArgumentAST *> ObjCMessageArgumentListAST;
typedef List<ObjCSelectorArgumentAST *> ObjCSelectorArgumentListAST;
......
......@@ -1198,7 +1198,7 @@ static inline int classify11(const char *s, bool q) {
return T_IDENTIFIER;
}
static inline int classify12(const char *s, bool) {
static inline int classify12(const char *s, bool q) {
if (s[0] == '_') {
if (s[1] == '_') {
if (s[2] == 'v') {
......@@ -1224,6 +1224,31 @@ static inline int classify12(const char *s, bool) {
}
}
}
else if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'I') {
if (s[3] == 'N') {
if (s[4] == 'T') {
if (s[5] == 'E') {
if (s[6] == 'R') {
if (s[7] == 'F') {
if (s[8] == 'A') {
if (s[9] == 'C') {
if (s[10] == 'E') {
if (s[11] == 'S') {
return T_Q_INTERFACES;
}
}
}
}
}
}
}
}
}
}
}
}
else if (s[0] == 'd') {
if (s[1] == 'y') {
if (s[2] == 'n') {
......
......@@ -293,6 +293,7 @@ void Parser::skipUntilDeclaration()
case T_Q_PROPERTY:
case T_Q_ENUMS:
case T_Q_FLAGS:
case T_Q_INTERFACES:
// Qt function specifiers
case T_Q_SIGNAL:
......@@ -1942,6 +1943,78 @@ bool Parser::parseQtFlags(DeclarationAST *&node)
return true;
}
// class-specifier ::=
// c++-class-specifier
// q-tag
// q-enums-of-flags
// q-class-info
// q-interfaces
// q-private-slot
//
// declaration ::=
// c++-declaration
// q-declare-interface
// q-declare-metatype
//
// q-tag ::=
// Q_OBJECT
// Q_GADGET
//
// q-enums-or-flags ::=
// (Q_ENUMS | Q_FLAGS) LPAREN name+ RPAREN
//
// q-class-info ::=
// Q_CLASS_INFO LPAREN string-literal COMMA STRING_LITERAL RPAREN
// Q_CLASS_INFO LPAREN string-literal COMMA IDENTIFIER LPAREN STRING_LITERAL RPAREN RPAREN
// q-interfaces ::=
// Q_INTERFACES LPAREN (name q-constraints)* RPAREN
//
// q-constraints ::=
// (COLON name)*
bool Parser::parseQtInterfaces(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_Q_INTERFACES)
return false;
QtInterfacesDeclarationAST *ast = new (_pool) QtInterfacesDeclarationAST;
ast->interfaces_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
for (QtInterfaceNameListAST **iter = &ast->interface_name_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
NameAST *name_ast = 0;
if (!parseName(name_ast))
break;
*iter = new (_pool) QtInterfaceNameListAST;
(*iter)->value = new (_pool) QtInterfaceNameAST;
(*iter)->value->interface_name = name_ast;
for (NameListAST **iter2 = &(*iter)->value->constraint_list; LA() && LA() == T_COLON; iter2 = &(*iter2)->next) {
/*unsigned colon_token =*/ consumeToken();
NameAST *name_ast2 = 0;
if (!parseName(name_ast2))
break;
*iter2 = new (_pool) NameListAST;
(*iter2)->value = name_ast2;
}
}
match(T_RPAREN, &ast->rparen_token);
node = ast;
return true;
}
// q-private-slot ::=
// Q_PRIVATE_SLOT LPAREN IDENTIFIER (LPAREN RPAREN)? COMMA q-function-declaration RPAREN
//
// q-function-declaration ::=
// decl-specifier-list declarator [+ check for the function-declarator]
//
// q-declare-interface ::=
// Q_DECLARE_INTERFACE LPAREN name COMMA (STRING_LITERAL | IDENTIFIER) RPAREN
//
// q-declare-metatype ::=
// Q_DECLARE_METATYPE LPAREN name RPAREN SEMICOLON? [warning]
bool Parser::parseMemberSpecification(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
......@@ -1971,6 +2044,9 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
case T_Q_FLAGS:
return parseQtFlags(node);
case T_Q_INTERFACES:
return parseQtInterfaces(node);
default:
return parseSimpleDeclaration(node, /*acceptStructDeclarator=*/true);
} // switch
......
......@@ -81,6 +81,7 @@ public:
bool parseQtPropertyDeclaration(DeclarationAST *&node);
bool parseQtEnumDeclaration(DeclarationAST *&node);
bool parseQtFlags(DeclarationAST *&node);
bool parseQtInterfaces(DeclarationAST *&node);
bool parseAdditiveExpression(ExpressionAST *&node);
bool parseAndExpression(ExpressionAST *&node);
bool parseAsmDefinition(DeclarationAST *&node);
......
......@@ -93,7 +93,7 @@ static const char *token_names[] = {
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
("Q_INVOKABLE"), ("Q_PROPERTY"), ("Q_ENUMS"), ("Q_FLAGS")
("Q_INVOKABLE"), ("Q_PROPERTY"), ("Q_INTERFACES"), ("Q_ENUMS"), ("Q_FLAGS")
};
Token::Token() :
......
......@@ -240,6 +240,7 @@ enum Kind {
T_Q_Q,
T_Q_INVOKABLE,
T_Q_PROPERTY,
T_Q_INTERFACES,
T_Q_ENUMS,
T_Q_FLAGS,
T_LAST_KEYWORD = T_Q_FLAGS,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment