forked from qt-creator/qt-creator
Parse and create AST nodes for the Q_MOC_RUN extensions.
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user