summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.cpp36
-rw-r--r--src/shared/cplusplus/AST.h48
-rw-r--r--src/shared/cplusplus/ASTClone.cpp25
-rw-r--r--src/shared/cplusplus/ASTMatch0.cpp16
-rw-r--r--src/shared/cplusplus/ASTMatcher.cpp42
-rw-r--r--src/shared/cplusplus/ASTMatcher.h2
-rw-r--r--src/shared/cplusplus/ASTVisit.cpp16
-rw-r--r--src/shared/cplusplus/ASTVisitor.h4
-rw-r--r--src/shared/cplusplus/ASTfwd.h2
-rw-r--r--src/shared/cplusplus/Keywords.cpp126
-rw-r--r--src/shared/cplusplus/Parser.cpp41
-rw-r--r--src/shared/cplusplus/Token.cpp5
-rw-r--r--src/shared/cplusplus/Token.h6
13 files changed, 364 insertions, 5 deletions
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 6da6f08c65..752a383a33 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -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;
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index f9f13a0b7a..85040258e2 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -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:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 1e58c3f692..7920644c43 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -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;
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index d594b441d2..0b97e9c7fa 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -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())
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index 044f7b1f06..e9734c661f 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -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;
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index 3de5b736a8..baae1ce874 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -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);
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 0e9575240d..f58974f016 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -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)) {
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 25a9aa2741..4490f11faa 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -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 *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index d068f12036..f8f129acb4 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -167,6 +167,8 @@ class QtInterfaceNameAST;
class QtInterfacesDeclarationAST;
class QtMemberDeclarationAST;
class QtMethodAST;
+class QtObjectTagAST;
+class QtPrivateSlotAST;
class QtPropertyDeclarationAST;
class QtPropertyDeclarationItemAST;
class QualifiedNameAST;
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index 7ce723e3cc..0e6beaf06f 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -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
}
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 95372cbad5..ce5afdd5fa 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -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);
diff --git a/src/shared/cplusplus/Token.cpp b/src/shared/cplusplus/Token.cpp
index cafce02eac..2bb8763e66 100644
--- a/src/shared/cplusplus/Token.cpp
+++ b/src/shared/cplusplus/Token.cpp
@@ -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() :
diff --git a/src/shared/cplusplus/Token.h b/src/shared/cplusplus/Token.h
index e71d25bf62..2c85855154 100644
--- a/src/shared/cplusplus/Token.h
+++ b/src/shared/cplusplus/Token.h
@@ -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,