forked from qt-creator/qt-creator
C++: Parse emit/Q_EMIT properly
The parser now understands emit/Q_EMIT as an expression statement. Also, the recent fixes in the preprocessor introduced a side-effect in the hanlding of code such as: emit signal(); Member signal started being treated as a local use (parsed as a declaration) and possibily being highlighted as unused variable. Previously that worked by accident since there was an inconsistency in the preprocessor on which only object-like macros were being expanded even when the "no expand" flag was set. Then, the code mentioned above was being parsed as an expression, what kind of worked. Change-Id: I47a68ed4c1c1702872620b8ed7c7264fb0997034 Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
This commit is contained in:
20
src/libs/3rdparty/cplusplus/Keywords.cpp
vendored
20
src/libs/3rdparty/cplusplus/Keywords.cpp
vendored
@@ -136,6 +136,13 @@ static inline int classify4(const char *s, bool q, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (q && s[1] == 'm') {
|
||||||
|
if (s[2] == 'i') {
|
||||||
|
if (s[3] == 't') {
|
||||||
|
return T_EMIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (s[0] == 'g') {
|
else if (s[0] == 'g') {
|
||||||
if (s[1] == 'o') {
|
if (s[1] == 'o') {
|
||||||
@@ -417,6 +424,19 @@ static inline int classify6(const char *s, bool q, bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (q && s[0] == 'Q') {
|
||||||
|
if (s[1] == '_') {
|
||||||
|
if (s[2] == 'E') {
|
||||||
|
if (s[3] == 'M') {
|
||||||
|
if (s[4] == 'I') {
|
||||||
|
if (s[5] == 'T') {
|
||||||
|
return T_Q_EMIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (s[0] == 'r') {
|
else if (s[0] == 'r') {
|
||||||
if (s[1] == 'e') {
|
if (s[1] == 'e') {
|
||||||
if (s[2] == 't') {
|
if (s[2] == 't') {
|
||||||
|
17
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
17
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -2947,6 +2947,23 @@ bool Parser::parseStatement(StatementAST *&node)
|
|||||||
node = ast;
|
node = ast;
|
||||||
} return true;
|
} return true;
|
||||||
|
|
||||||
|
case T_EMIT:
|
||||||
|
case T_Q_EMIT: {
|
||||||
|
// Simply skip the emit token and parse as an expression statement - no strong
|
||||||
|
// reason to have an specific ast type.
|
||||||
|
consumeToken();
|
||||||
|
ExpressionAST *expression = 0;
|
||||||
|
if (parsePostfixExpression(expression)) {
|
||||||
|
ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
|
||||||
|
ast->expression = expression;
|
||||||
|
match(T_SEMICOLON, &ast->semicolon_token);
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
error(cursor(), "expected statement");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
|
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
|
||||||
return parseLabeledStatement(node);
|
return parseLabeledStatement(node);
|
||||||
|
4
src/libs/3rdparty/cplusplus/Token.cpp
vendored
4
src/libs/3rdparty/cplusplus/Token.cpp
vendored
@@ -71,10 +71,10 @@ static const char *token_names[] = {
|
|||||||
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
|
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
|
||||||
|
|
||||||
// Qt keywords
|
// Qt keywords
|
||||||
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
|
("emit"), ("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
|
||||||
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
|
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
|
||||||
("Q_INVOKABLE"), ("Q_PROPERTY"), ("T_Q_PRIVATE_PROPERTY"),
|
("Q_INVOKABLE"), ("Q_PROPERTY"), ("T_Q_PRIVATE_PROPERTY"),
|
||||||
("Q_INTERFACES"), ("Q_ENUMS"), ("Q_FLAGS"),
|
("Q_INTERFACES"), ("Q_EMIT"), ("Q_ENUMS"), ("Q_FLAGS"),
|
||||||
("Q_PRIVATE_SLOT"), ("Q_DECLARE_INTERFACE"), ("Q_OBJECT"), ("Q_GADGET"),
|
("Q_PRIVATE_SLOT"), ("Q_DECLARE_INTERFACE"), ("Q_OBJECT"), ("Q_GADGET"),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
4
src/libs/3rdparty/cplusplus/Token.h
vendored
4
src/libs/3rdparty/cplusplus/Token.h
vendored
@@ -217,7 +217,8 @@ enum Kind {
|
|||||||
T_FIRST_QT_KEYWORD,
|
T_FIRST_QT_KEYWORD,
|
||||||
|
|
||||||
// Qt keywords
|
// Qt keywords
|
||||||
T_SIGNAL = T_FIRST_QT_KEYWORD,
|
T_EMIT = T_FIRST_QT_KEYWORD,
|
||||||
|
T_SIGNAL,
|
||||||
T_SLOT,
|
T_SLOT,
|
||||||
T_Q_SIGNAL,
|
T_Q_SIGNAL,
|
||||||
T_Q_SLOT,
|
T_Q_SLOT,
|
||||||
@@ -230,6 +231,7 @@ enum Kind {
|
|||||||
T_Q_PROPERTY,
|
T_Q_PROPERTY,
|
||||||
T_Q_PRIVATE_PROPERTY,
|
T_Q_PRIVATE_PROPERTY,
|
||||||
T_Q_INTERFACES,
|
T_Q_INTERFACES,
|
||||||
|
T_Q_EMIT,
|
||||||
T_Q_ENUMS,
|
T_Q_ENUMS,
|
||||||
T_Q_FLAGS,
|
T_Q_FLAGS,
|
||||||
T_Q_PRIVATE_SLOT,
|
T_Q_PRIVATE_SLOT,
|
||||||
|
@@ -1813,6 +1813,10 @@ bool Preprocessor::isQtReservedWord(const ByteArrayRef ¯oId)
|
|||||||
return true;
|
return true;
|
||||||
else if (size == 5 && macroId.at(0) == 's' && macroId == "slots")
|
else if (size == 5 && macroId.at(0) == 's' && macroId == "slots")
|
||||||
return true;
|
return true;
|
||||||
|
else if (size == 4 && macroId.at(0) == 'e' && macroId == "emit")
|
||||||
|
return true;
|
||||||
|
else if (size == 6 && macroId.at(0) == 'Q' && macroId == "Q_EMIT")
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user