Commit 2d45bb80 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Parse and create AST nodes for the Q_MOC_RUN extensions.

parent bfaf247a
......@@ -144,6 +144,42 @@ unsigned AccessDeclarationAST::lastToken() const
return access_specifier_token + 1;
}
unsigned QtObjectTagAST::firstToken() const
{
return q_object_token;
}
unsigned QtObjectTagAST::lastToken() const
{
return q_object_token + 1;
}
unsigned QtPrivateSlotAST::firstToken() const
{
return q_private_slot_token;
}
unsigned QtPrivateSlotAST::lastToken() const
{
if (rparen_token)
return rparen_token + 1;
else if (declarator)
return declarator->lastToken();
else if (type_specifiers)
type_specifiers->lastToken();
else if (comma_token)
return comma_token + 1;
else if (dptr_rparen_token)
return dptr_rparen_token + 1;
else if (dptr_lparen_token)
return dptr_lparen_token + 1;
else if (dptr_token)
return dptr_token + 1;
else if (lparen_token)
return lparen_token + 1;
return q_private_slot_token + 1;
}
unsigned QtPropertyDeclarationItemAST::firstToken() const
{
return item_name_token;
......
......@@ -101,7 +101,7 @@ public:
return lastValue;
}
_Tp value;
List *next;
};
......@@ -260,6 +260,8 @@ public:
virtual QtInterfacesDeclarationAST *asQtInterfacesDeclaration() { return 0; }
virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return 0; }
virtual QtMethodAST *asQtMethod() { return 0; }
virtual QtObjectTagAST *asQtObjectTag() { return 0; }
virtual QtPrivateSlotAST *asQtPrivateSlot() { return 0; }
virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return 0; }
virtual QtPropertyDeclarationItemAST *asQtPropertyDeclarationItem() { return 0; }
virtual QualifiedNameAST *asQualifiedName() { return 0; }
......@@ -578,6 +580,50 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QtObjectTagAST: public DeclarationAST
{
public:
unsigned q_object_token;
public:
virtual QtObjectTagAST *asQtObjectTag() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual QtObjectTagAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT QtPrivateSlotAST: public DeclarationAST
{
public:
unsigned q_private_slot_token;
unsigned lparen_token;
unsigned dptr_token;
unsigned dptr_lparen_token;
unsigned dptr_rparen_token;
unsigned comma_token;
SpecifierListAST *type_specifiers;
DeclaratorAST *declarator;
unsigned rparen_token;
public:
virtual QtPrivateSlotAST *asQtPrivateSlot() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual QtPrivateSlotAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class QtPropertyDeclarationItemAST: public AST
{
public:
......
......@@ -155,6 +155,31 @@ AccessDeclarationAST *AccessDeclarationAST::clone(MemoryPool *pool) const
return ast;
}
QtObjectTagAST *QtObjectTagAST::clone(MemoryPool *pool) const
{
QtObjectTagAST *ast = new (pool) QtObjectTagAST;
ast->q_object_token = q_object_token;
return ast;
}
QtPrivateSlotAST *QtPrivateSlotAST::clone(MemoryPool *pool) const
{
QtPrivateSlotAST *ast = new (pool) QtPrivateSlotAST;
ast->q_private_slot_token = q_private_slot_token;
ast->lparen_token = lparen_token;
ast->dptr_token = dptr_token;
ast->dptr_lparen_token = dptr_lparen_token;
ast->dptr_rparen_token = dptr_rparen_token;
ast->comma_token = comma_token;
for (SpecifierListAST *iter = type_specifiers, **ast_iter = &ast->type_specifiers;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
if (declarator)
ast->declarator = declarator->clone(pool);
ast->rparen_token = rparen_token;
return ast;
}
QtPropertyDeclarationItemAST *QtPropertyDeclarationItemAST::clone(MemoryPool *pool) const
{
QtPropertyDeclarationItemAST *ast = new (pool) QtPropertyDeclarationItemAST;
......
......@@ -121,6 +121,22 @@ bool AccessDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool QtObjectTagAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QtObjectTagAST *_other = pattern->asQtObjectTag())
return matcher->match(this, _other);
return false;
}
bool QtPrivateSlotAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QtPrivateSlotAST *_other = pattern->asQtPrivateSlot())
return matcher->match(this, _other);
return false;
}
bool QtPropertyDeclarationItemAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (QtPropertyDeclarationItemAST *_other = pattern->asQtPropertyDeclarationItem())
......
......@@ -231,6 +231,48 @@ bool ASTMatcher::match(AccessDeclarationAST *node, AccessDeclarationAST *pattern
return true;
}
bool ASTMatcher::match(QtObjectTagAST *node, QtObjectTagAST *pattern)
{
(void) node;
(void) pattern;
pattern->q_object_token = node->q_object_token;
return true;
}
bool ASTMatcher::match(QtPrivateSlotAST *node, QtPrivateSlotAST *pattern)
{
(void) node;
(void) pattern;
pattern->q_private_slot_token = node->q_private_slot_token;
pattern->lparen_token = node->lparen_token;
pattern->dptr_token = node->dptr_token;
pattern->dptr_lparen_token = node->dptr_lparen_token;
pattern->dptr_rparen_token = node->dptr_rparen_token;
pattern->comma_token = node->comma_token;
if (! pattern->type_specifiers)
pattern->type_specifiers = node->type_specifiers;
else if (! AST::match(node->type_specifiers, pattern->type_specifiers, this))
return false;
if (! pattern->declarator)
pattern->declarator = node->declarator;
else if (! AST::match(node->declarator, pattern->declarator, this))
return false;
pattern->rparen_token = node->rparen_token;
return true;
}
bool ASTMatcher::match(QtPropertyDeclarationItemAST *node, QtPropertyDeclarationItemAST *pattern)
{
(void) node;
......
......@@ -40,6 +40,8 @@ public:
virtual ~ASTMatcher();
virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
virtual bool match(QtObjectTagAST *node, QtObjectTagAST *pattern);
virtual bool match(QtPrivateSlotAST *node, QtPrivateSlotAST *pattern);
virtual bool match(QtPropertyDeclarationAST *node, QtPropertyDeclarationAST *pattern);
virtual bool match(QtEnumDeclarationAST *node, QtEnumDeclarationAST *pattern);
virtual bool match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *pattern);
......
......@@ -123,6 +123,22 @@ void AccessDeclarationAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void QtObjectTagAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
}
visitor->endVisit(this);
}
void QtPrivateSlotAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(type_specifiers, visitor);
accept(declarator, visitor);
}
visitor->endVisit(this);
}
void QtPropertyDeclarationItemAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
......
......@@ -103,6 +103,8 @@ public:
virtual void postVisit(AST *) {}
virtual bool visit(AccessDeclarationAST *) { return true; }
virtual bool visit(QtObjectTagAST *) { return true; }
virtual bool visit(QtPrivateSlotAST *) { return true; }
virtual bool visit(QtPropertyDeclarationAST *) { return true; }
virtual bool visit(QtEnumDeclarationAST *) { return true; }
virtual bool visit(QtFlagsDeclarationAST *) { return true; }
......@@ -235,6 +237,8 @@ public:
virtual bool visit(ObjCSynchronizedStatementAST *) { return true; }
virtual void endVisit(AccessDeclarationAST *) { }
virtual void endVisit(QtObjectTagAST *) {}
virtual void endVisit(QtPrivateSlotAST *) {}
virtual void endVisit(QtPropertyDeclarationAST *) { }
virtual void endVisit(QtEnumDeclarationAST *) { }
virtual void endVisit(QtFlagsDeclarationAST *) { }
......
......@@ -167,6 +167,8 @@ class QtInterfaceNameAST;
class QtInterfacesDeclarationAST;
class QtMemberDeclarationAST;
class QtMethodAST;
class QtObjectTagAST;
class QtPrivateSlotAST;
class QtPropertyDeclarationAST;
class QtPropertyDeclarationItemAST;
class QualifiedNameAST;
......
......@@ -912,7 +912,33 @@ static inline int classify8(const char *s, bool q) {
}
else if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'S') {
if (s[2] == 'G') {
if (s[3] == 'A') {
if (s[4] == 'D') {
if (s[5] == 'G') {
if (s[6] == 'E') {
if (s[7] == 'T') {
return T_Q_GADGET;
}
}
}
}
}
}
else if (s[2] == 'O') {
if (s[3] == 'B') {
if (s[4] == 'J') {
if (s[5] == 'E') {
if (s[6] == 'C') {
if (s[7] == 'T') {
return T_Q_OBJECT;
}
}
}
}
}
}
else if (s[2] == 'S') {
if (s[3] == 'I') {
if (s[4] == 'G') {
if (s[5] == 'N') {
......@@ -1103,7 +1129,24 @@ static inline int classify10(const char *s, bool q) {
}
else if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'P') {
if (s[2] == 'O') {
if (s[3] == 'V') {
if (s[4] == 'E') {
if (s[5] == 'R') {
if (s[6] == 'R') {
if (s[7] == 'I') {
if (s[8] == 'D') {
if (s[9] == 'E') {
return T_Q_PROPERTY; // Q_OVERRIDE is just an alias for Q_PROPERTY
}
}
}
}
}
}
}
}
else if (s[2] == 'P') {
if (s[3] == 'R') {
if (s[4] == 'O') {
if (s[5] == 'P') {
......@@ -1345,6 +1388,83 @@ static inline int classify16(const char *s, bool) {
return T_IDENTIFIER;
}
static inline int classify14(const char *s, bool q) {
if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'P') {
if (s[3] == 'R') {
if (s[4] == 'I') {
if (s[5] == 'V') {
if (s[6] == 'A') {
if (s[7] == 'T') {
if (s[8] == 'E') {
if (s[9] == '_') {
if (s[10] == 'S') {
if (s[11] == 'L') {
if (s[12] == 'O') {
if (s[13] == 'T') {
return T_Q_PRIVATE_SLOT;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return T_IDENTIFIER;
}
static inline int classify19(const char *s, bool q) {
if (q && s[0] == 'Q') {
if (s[1] == '_') {
if (s[2] == 'D') {
if (s[3] == 'E') {
if (s[4] == 'C') {
if (s[5] == 'L') {
if (s[6] == 'A') {
if (s[7] == 'R') {
if (s[8] == 'E') {
if (s[9] == '_') {
if (s[10] == 'I') {
if (s[11] == 'N') {
if (s[12] == 'T') {
if (s[13] == 'E') {
if (s[14] == 'R') {
if (s[15] == 'F') {
if (s[16] == 'A') {
if (s[17] == 'C') {
if (s[18] == 'E') {
return T_Q_DECLARE_INTERFACE;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return T_IDENTIFIER;
}
int Lexer::classify(const char *s, int n, bool q) {
switch (n) {
case 2: return classify2(s, q);
......@@ -1359,7 +1479,9 @@ int Lexer::classify(const char *s, int n, bool q) {
case 11: return classify11(s, q);
case 12: return classify12(s, q);
case 13: return classify13(s, q);
case 14: return classify14(s, q);
case 16: return classify16(s, q);
case 19: return classify19(s, q);
default: return T_IDENTIFIER;
} // switch
}
......
......@@ -609,6 +609,21 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
case T_AT_IMPLEMENTATION:
return parseObjCImplementation(node);
case T_Q_DECLARE_INTERFACE:
{
consumeToken();
unsigned lparen_token = 0;
match(T_LPAREN, &lparen_token);
NameAST *name = 0;
parseName(name);
unsigned comma_token = 0;
match(T_COMMA, &comma_token);
unsigned string_literal = 0;
match(T_STRING_LITERAL, &string_literal);
unsigned rparen_token = 0;
match(T_RPAREN, &rparen_token);
} return true;
case T_AT_END:
// TODO: should this be done here, or higher-up?
_translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
......@@ -2019,6 +2034,32 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
switch (LA()) {
case T_Q_OBJECT:
case T_Q_GADGET:
{
QtObjectTagAST *ast = new (_pool) QtObjectTagAST;
ast->q_object_token = consumeToken();
node = ast;
return true;
}
case T_Q_PRIVATE_SLOT:
{
QtPrivateSlotAST *ast = new (_pool) QtPrivateSlotAST;
ast->q_private_slot_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
match(T_IDENTIFIER, &ast->dptr_token);
if (LA() == T_LPAREN) {
ast->dptr_lparen_token = consumeToken();
match(T_RPAREN, &ast->dptr_rparen_token);
}
match(T_COMMA, &ast->comma_token);
parseTypeSpecifier(ast->type_specifiers);
parseDeclarator(ast->declarator);
match(T_RPAREN, &ast->rparen_token);
node = ast;
} return true;
case T_SEMICOLON:
return parseEmptyDeclaration(node);
......
......@@ -91,9 +91,12 @@ static const char *token_names[] = {
("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
// Qt keywords
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
("Q_INVOKABLE"), ("Q_PROPERTY"), ("Q_INTERFACES"), ("Q_ENUMS"), ("Q_FLAGS")
("Q_INVOKABLE"), ("Q_PROPERTY"), ("Q_INTERFACES"), ("Q_ENUMS"), ("Q_FLAGS"),
("Q_PRIVATE_SLOT"), ("Q_DECLARE_INTERFACE"), ("Q_OBJECT"), ("Q_GADGET"),
};
Token::Token() :
......
......@@ -243,7 +243,11 @@ enum Kind {
T_Q_INTERFACES,
T_Q_ENUMS,
T_Q_FLAGS,
T_LAST_KEYWORD = T_Q_FLAGS,
T_Q_PRIVATE_SLOT,
T_Q_DECLARE_INTERFACE,
T_Q_OBJECT,
T_Q_GADGET,
T_LAST_KEYWORD = T_Q_GADGET,
// aliases
T_OR = T_PIPE_PIPE,
......
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