Split Objective-C keyword parsing to handle the '@' separately.

Because apparently, while designing the Objective-C language, somebody
thought it was a world-class idea to allow any white-space between the
'@' character and the subsequent keyword. With this fix, we now
correctly parse:
    @  dynamic
and:
    @
      selector
and:
    @"foo"
     "bar"
    @"mooze"
(This last one is 1 single string split over multiple lines.)
Wonderful, isn't it?

What we (and Clang) do not support, but what GCC supports is something
like:
   @"foo"@@  "bar"  @"mooze"  @@
which is equivalent to @"foobarmooze".
This commit is contained in:
Erik Verbruggen
2010-02-14 14:41:51 +01:00
parent abdd404ff5
commit 2a59d2ae0c
14 changed files with 410 additions and 367 deletions

View File

@@ -1561,14 +1561,16 @@ unsigned SizeofExpressionAST::lastToken() const
unsigned StringLiteralAST::firstToken() const
{
return literal_token;
return at_token;
}
unsigned StringLiteralAST::lastToken() const
{
if (next)
return next->lastToken();
return literal_token + 1;
if (literal_token)
return literal_token + 1;
return at_token + 1;
}
@@ -1910,7 +1912,7 @@ unsigned ObjCClassForwardDeclarationAST::firstToken() const
if (attribute_list)
return attribute_list->firstToken();
return class_token;
return at_token;
}
unsigned ObjCClassForwardDeclarationAST::lastToken() const
@@ -1921,7 +1923,10 @@ unsigned ObjCClassForwardDeclarationAST::lastToken() const
else if (identifier_list)
return identifier_list->lastToken();
return class_token + 1;
else if (class_token)
return class_token + 1;
else
return at_token + 1;
}
unsigned ObjCProtocolForwardDeclarationAST::firstToken() const
@@ -1929,7 +1934,7 @@ unsigned ObjCProtocolForwardDeclarationAST::firstToken() const
if (attribute_list)
return attribute_list->firstToken();
return protocol_token;
return at_token;
}
unsigned ObjCProtocolForwardDeclarationAST::lastToken() const
@@ -1940,7 +1945,10 @@ unsigned ObjCProtocolForwardDeclarationAST::lastToken() const
else if (identifier_list)
return identifier_list->lastToken();
return protocol_token + 1;
else if (protocol_token)
return protocol_token + 1;
else
return at_token + 1;
}
unsigned ObjCClassDeclarationAST::firstToken() const
@@ -1948,15 +1956,14 @@ unsigned ObjCClassDeclarationAST::firstToken() const
if (attribute_list)
return attribute_list->firstToken();
if (interface_token)
return interface_token;
else
return implementation_token;
return at_token;
}
unsigned ObjCClassDeclarationAST::lastToken() const
{
if (end_token) return end_token + 1;
if (ending_at_token)
return ending_at_token + 1;
if (member_declaration_list) return member_declaration_list->lastToken();
if (inst_vars_decl) return inst_vars_decl->lastToken();
if (protocol_refs)
@@ -1974,21 +1981,25 @@ unsigned ObjCClassDeclarationAST::lastToken() const
if (interface_token)
return interface_token + 1;
else
else if (implementation_token)
return implementation_token + 1;
else
return at_token + 1;
}
unsigned ObjCProtocolDeclarationAST::firstToken() const
{
if (attribute_list)
return attribute_list->firstToken();
return protocol_token;
return at_token;
}
unsigned ObjCProtocolDeclarationAST::lastToken() const
{
if (end_token)
return end_token + 1;
else if (ending_at_token)
return ending_at_token + 1;
else if (member_declaration_list)
return member_declaration_list->lastToken();
@@ -2001,8 +2012,10 @@ unsigned ObjCProtocolDeclarationAST::lastToken() const
else if (attribute_list)
return attribute_list->lastToken();
return protocol_token + 1;
else if (protocol_token)
return protocol_token + 1;
else
return at_token + 1;
}
unsigned ObjCProtocolRefsAST::firstToken() const
@@ -2063,7 +2076,7 @@ unsigned ObjCMessageArgumentAST::lastToken() const
unsigned ObjCProtocolExpressionAST::firstToken() const
{
return protocol_token;
return at_token;
}
unsigned ObjCProtocolExpressionAST::lastToken() const
@@ -2077,7 +2090,10 @@ unsigned ObjCProtocolExpressionAST::lastToken() const
if (lparen_token)
return lparen_token + 1;
return protocol_token + 1;
if (protocol_token)
return protocol_token + 1;
return at_token + 1;
}
unsigned ObjCTypeNameAST::firstToken() const
@@ -2101,7 +2117,7 @@ unsigned ObjCTypeNameAST::lastToken() const
unsigned ObjCEncodeExpressionAST::firstToken() const
{
return encode_token;
return at_token;
}
unsigned ObjCEncodeExpressionAST::lastToken() const
@@ -2109,7 +2125,10 @@ unsigned ObjCEncodeExpressionAST::lastToken() const
if (type_name)
return type_name->lastToken();
return encode_token + 1;
if (encode_token)
return encode_token + 1;
return at_token + 1;
}
unsigned ObjCSelectorWithoutArgumentsAST::firstToken() const
@@ -2147,7 +2166,7 @@ unsigned ObjCSelectorWithArgumentsAST::lastToken() const
unsigned ObjCSelectorExpressionAST::firstToken() const
{
return selector_token;
return at_token;
}
unsigned ObjCSelectorExpressionAST::lastToken() const
@@ -2158,7 +2177,9 @@ unsigned ObjCSelectorExpressionAST::lastToken() const
return selector->lastToken();
if (lparen_token)
return rparen_token + 1;
return selector_token + 1;
if (selector_token)
return selector_token + 1;
return at_token + 1;
}
unsigned ObjCInstanceVariablesDeclarationAST::firstToken() const
@@ -2179,12 +2200,15 @@ unsigned ObjCInstanceVariablesDeclarationAST::lastToken() const
unsigned ObjCVisibilityDeclarationAST::firstToken() const
{
return visibility_token;
return at_token;
}
unsigned ObjCVisibilityDeclarationAST::lastToken() const
{
return visibility_token + 1;
if (visibility_token)
return visibility_token + 1;
else
return at_token + 1;
}
unsigned ObjCPropertyAttributeAST::firstToken() const
@@ -2207,7 +2231,7 @@ unsigned ObjCPropertyDeclarationAST::firstToken() const
if (attribute_list)
return attribute_list->firstToken();
return property_token;
return at_token;
}
unsigned ObjCPropertyDeclarationAST::lastToken() const
@@ -2220,8 +2244,10 @@ unsigned ObjCPropertyDeclarationAST::lastToken() const
return property_attribute_list->lastToken();
else if (lparen_token)
return lparen_token + 1;
return property_token + 1;
else if (property_token)
return property_token + 1;
else
return at_token + 1;
}
unsigned ObjCMessageArgumentDeclarationAST::firstToken() const
@@ -2354,7 +2380,7 @@ unsigned ObjCFastEnumerationAST::lastToken() const
unsigned ObjCSynchronizedStatementAST::firstToken() const
{
return synchronized_token;
return at_token;
}
unsigned ObjCSynchronizedStatementAST::lastToken() const
@@ -2363,5 +2389,6 @@ unsigned ObjCSynchronizedStatementAST::lastToken() const
if (rparen_token) return rparen_token + 1;
if (synchronized_object) return synchronized_object->lastToken();
if (lparen_token) return lparen_token + 1;
return synchronized_token + 1;
if (synchronized_token) return synchronized_token + 1;
return at_token + 1;
}

View File

@@ -2275,6 +2275,7 @@ protected:
class CPLUSPLUS_EXPORT StringLiteralAST: public ExpressionAST
{
public:
unsigned at_token;
unsigned literal_token;
StringLiteralAST *next;
@@ -2588,6 +2589,7 @@ class CPLUSPLUS_EXPORT ObjCClassForwardDeclarationAST: public DeclarationAST
{
public:
SpecifierListAST *attribute_list;
unsigned at_token;
unsigned class_token;
NameListAST *identifier_list;
unsigned semicolon_token;
@@ -2612,6 +2614,7 @@ class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
{
public:
SpecifierListAST *attribute_list;
unsigned at_token;
unsigned interface_token;
unsigned implementation_token;
NameAST *class_name;
@@ -2623,6 +2626,7 @@ public:
ObjCProtocolRefsAST *protocol_refs;
ObjCInstanceVariablesDeclarationAST *inst_vars_decl;
DeclarationListAST *member_declaration_list;
unsigned ending_at_token;
unsigned end_token;
public: // annotations
@@ -2645,6 +2649,7 @@ class CPLUSPLUS_EXPORT ObjCProtocolForwardDeclarationAST: public DeclarationAST
{
public:
SpecifierListAST *attribute_list;
unsigned at_token;
unsigned protocol_token;
NameListAST *identifier_list;
unsigned semicolon_token;
@@ -2669,10 +2674,12 @@ class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST
{
public:
SpecifierListAST *attribute_list;
unsigned at_token;
unsigned protocol_token;
NameAST *name;
ObjCProtocolRefsAST *protocol_refs;
DeclarationListAST *member_declaration_list;
unsigned ending_at_token;
unsigned end_token;
public: // annotations
@@ -2754,6 +2761,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCProtocolExpressionAST: public ExpressionAST
{
public:
unsigned at_token;
unsigned protocol_token;
unsigned lparen_token;
unsigned identifier_token;
@@ -2796,6 +2804,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST
{
public:
unsigned at_token;
unsigned encode_token;
ObjCTypeNameAST *type_name;
@@ -2870,6 +2879,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCSelectorExpressionAST: public ExpressionAST
{
public:
unsigned at_token;
unsigned selector_token;
unsigned lparen_token;
ObjCSelectorAST *selector;
@@ -2911,6 +2921,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCVisibilityDeclarationAST: public DeclarationAST
{
public:
unsigned at_token;
unsigned visibility_token;
public:
@@ -2950,6 +2961,7 @@ class CPLUSPLUS_EXPORT ObjCPropertyDeclarationAST: public DeclarationAST
{
public:
SpecifierListAST *attribute_list;
unsigned at_token;
unsigned property_token;
unsigned lparen_token;
ObjCPropertyAttributeListAST *property_attribute_list;
@@ -3137,6 +3149,7 @@ protected:
class CPLUSPLUS_EXPORT ObjCSynchronizedStatementAST: public StatementAST
{
public:
unsigned at_token;
unsigned synchronized_token;
unsigned lparen_token;
ExpressionAST *synchronized_object;

View File

@@ -1064,6 +1064,7 @@ NestedExpressionAST *NestedExpressionAST::clone(MemoryPool *pool) const
StringLiteralAST *StringLiteralAST::clone(MemoryPool *pool) const
{
StringLiteralAST *ast = new (pool) StringLiteralAST;
ast->at_token = at_token;
ast->literal_token = literal_token;
if (next)
ast->next = next->clone(pool);
@@ -1232,6 +1233,7 @@ ObjCClassForwardDeclarationAST *ObjCClassForwardDeclarationAST::clone(MemoryPool
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->at_token = at_token;
ast->class_token = class_token;
for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
@@ -1246,6 +1248,7 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->at_token = at_token;
ast->interface_token = interface_token;
ast->implementation_token = implementation_token;
if (class_name)
@@ -1264,6 +1267,7 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
for (DeclarationListAST *iter = member_declaration_list, **ast_iter = &ast->member_declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->ending_at_token = ending_at_token;
ast->end_token = end_token;
return ast;
}
@@ -1274,6 +1278,7 @@ ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclarationAST::clone(Memo
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->at_token = at_token;
ast->protocol_token = protocol_token;
for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
@@ -1288,6 +1293,7 @@ ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool)
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->at_token = at_token;
ast->protocol_token = protocol_token;
if (name)
ast->name = name->clone(pool);
@@ -1296,6 +1302,7 @@ ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool)
for (DeclarationListAST *iter = member_declaration_list, **ast_iter = &ast->member_declaration_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) DeclarationListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->ending_at_token = ending_at_token;
ast->end_token = end_token;
return ast;
}
@@ -1337,6 +1344,7 @@ ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) cons
ObjCProtocolExpressionAST *ObjCProtocolExpressionAST::clone(MemoryPool *pool) const
{
ObjCProtocolExpressionAST *ast = new (pool) ObjCProtocolExpressionAST;
ast->at_token = at_token;
ast->protocol_token = protocol_token;
ast->lparen_token = lparen_token;
ast->identifier_token = identifier_token;
@@ -1358,6 +1366,7 @@ ObjCTypeNameAST *ObjCTypeNameAST::clone(MemoryPool *pool) const
ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const
{
ObjCEncodeExpressionAST *ast = new (pool) ObjCEncodeExpressionAST;
ast->at_token = at_token;
ast->encode_token = encode_token;
if (type_name)
ast->type_name = type_name->clone(pool);
@@ -1391,6 +1400,7 @@ ObjCSelectorWithArgumentsAST *ObjCSelectorWithArgumentsAST::clone(MemoryPool *po
ObjCSelectorExpressionAST *ObjCSelectorExpressionAST::clone(MemoryPool *pool) const
{
ObjCSelectorExpressionAST *ast = new (pool) ObjCSelectorExpressionAST;
ast->at_token = at_token;
ast->selector_token = selector_token;
ast->lparen_token = lparen_token;
if (selector)
@@ -1413,6 +1423,7 @@ ObjCInstanceVariablesDeclarationAST *ObjCInstanceVariablesDeclarationAST::clone(
ObjCVisibilityDeclarationAST *ObjCVisibilityDeclarationAST::clone(MemoryPool *pool) const
{
ObjCVisibilityDeclarationAST *ast = new (pool) ObjCVisibilityDeclarationAST;
ast->at_token = at_token;
ast->visibility_token = visibility_token;
return ast;
}
@@ -1433,6 +1444,7 @@ ObjCPropertyDeclarationAST *ObjCPropertyDeclarationAST::clone(MemoryPool *pool)
for (SpecifierListAST *iter = attribute_list, **ast_iter = &ast->attribute_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->at_token = at_token;
ast->property_token = property_token;
ast->lparen_token = lparen_token;
for (ObjCPropertyAttributeListAST *iter = property_attribute_list, **ast_iter = &ast->property_attribute_list;
@@ -1541,6 +1553,7 @@ ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const
ObjCSynchronizedStatementAST *ObjCSynchronizedStatementAST::clone(MemoryPool *pool) const
{
ObjCSynchronizedStatementAST *ast = new (pool) ObjCSynchronizedStatementAST;
ast->at_token = at_token;
ast->synchronized_token = synchronized_token;
ast->lparen_token = lparen_token;
if (synchronized_object)

View File

@@ -1771,6 +1771,8 @@ bool ASTMatcher::match(StringLiteralAST *node, StringLiteralAST *pattern)
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->literal_token = node->literal_token;
if (! pattern->next)
@@ -2063,6 +2065,8 @@ bool ASTMatcher::match(ObjCClassForwardDeclarationAST *node, ObjCClassForwardDec
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
return false;
pattern->at_token = node->at_token;
pattern->class_token = node->class_token;
if (! pattern->identifier_list)
@@ -2085,6 +2089,8 @@ bool ASTMatcher::match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *p
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
return false;
pattern->at_token = node->at_token;
pattern->interface_token = node->interface_token;
pattern->implementation_token = node->implementation_token;
@@ -2125,6 +2131,8 @@ bool ASTMatcher::match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *p
else if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
return false;
pattern->ending_at_token = node->ending_at_token;
pattern->end_token = node->end_token;
return true;
@@ -2140,6 +2148,8 @@ bool ASTMatcher::match(ObjCProtocolForwardDeclarationAST *node, ObjCProtocolForw
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
return false;
pattern->at_token = node->at_token;
pattern->protocol_token = node->protocol_token;
if (! pattern->identifier_list)
@@ -2162,6 +2172,8 @@ bool ASTMatcher::match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclaration
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
return false;
pattern->at_token = node->at_token;
pattern->protocol_token = node->protocol_token;
if (! pattern->name)
@@ -2179,6 +2191,8 @@ bool ASTMatcher::match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclaration
else if (! AST::match(node->member_declaration_list, pattern->member_declaration_list, this))
return false;
pattern->ending_at_token = node->ending_at_token;
pattern->end_token = node->end_token;
return true;
@@ -2246,6 +2260,8 @@ bool ASTMatcher::match(ObjCProtocolExpressionAST *node, ObjCProtocolExpressionAS
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->protocol_token = node->protocol_token;
pattern->lparen_token = node->lparen_token;
@@ -2281,6 +2297,8 @@ bool ASTMatcher::match(ObjCEncodeExpressionAST *node, ObjCEncodeExpressionAST *p
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->encode_token = node->encode_token;
if (! pattern->type_name)
@@ -2331,6 +2349,8 @@ bool ASTMatcher::match(ObjCSelectorExpressionAST *node, ObjCSelectorExpressionAS
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->selector_token = node->selector_token;
pattern->lparen_token = node->lparen_token;
@@ -2367,6 +2387,8 @@ bool ASTMatcher::match(ObjCVisibilityDeclarationAST *node, ObjCVisibilityDeclara
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->visibility_token = node->visibility_token;
return true;
@@ -2399,6 +2421,8 @@ bool ASTMatcher::match(ObjCPropertyDeclarationAST *node, ObjCPropertyDeclaration
else if (! AST::match(node->attribute_list, pattern->attribute_list, this))
return false;
pattern->at_token = node->at_token;
pattern->property_token = node->property_token;
pattern->lparen_token = node->lparen_token;
@@ -2587,6 +2611,8 @@ bool ASTMatcher::match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedState
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->synchronized_token = node->synchronized_token;
pattern->lparen_token = node->lparen_token;

View File

@@ -596,52 +596,11 @@ void Lexer::scan_helper(Token *tok)
tok->f.kind = T_COMMA;
break;
case '@':
tok->f.kind = T_AT;
break;
default: {
if (f._objCEnabled) {
if (ch == '@' && _yychar >= 'a' && _yychar <= 'z') {
const char *yytext = _currentChar;
do {
yyinp();
if (! (isalnum(_yychar) || _yychar == '_' || _yychar == '$'))
break;
} while (_yychar);
const int yylen = _currentChar - yytext;
tok->f.kind = classifyObjCAtKeyword(yytext, yylen);
break;
} else if (ch == '@' && _yychar == '"') {
// objc @string literals
ch = _yychar;
yyinp();
tok->f.kind = T_AT_STRING_LITERAL;
const char *yytext = _currentChar;
while (_yychar && _yychar != '"') {
if (_yychar != '\\')
yyinp();
else {
yyinp(); // skip `\\'
if (_yychar)
yyinp();
}
}
// assert(_yychar == '"');
int yylen = _currentChar - yytext;
if (_yychar == '"')
yyinp();
if (control())
tok->string = control()->findOrInsertStringLiteral(yytext, yylen);
break;
}
}
if (ch == 'L' && (_yychar == '"' || _yychar == '\'')) {
// wide char/string literals
ch = _yychar;
@@ -679,11 +638,18 @@ void Lexer::scan_helper(Token *tok)
while (std::isalnum(_yychar) || _yychar == '_' || _yychar == '$')
yyinp();
int yylen = _currentChar - yytext;
if (f._scanKeywords)
if (f._scanKeywords) {
tok->f.kind = classify(yytext, yylen, f._qtMocRunEnabled);
else
} else {
tok->f.kind = T_IDENTIFIER;
}
// ### is this correct w.r.t. the _scanKeywords?
if (f._objCEnabled && tok->f.kind == T_IDENTIFIER) {
tok->f.kind = classifyObjCAtKeyword(yytext, yylen);
if (tok->f.kind == T_ERROR)
tok->f.kind = T_IDENTIFIER;
}
// ### is this correct w.r.t. the _scanKeywords?
if (tok->f.kind == T_IDENTIFIER) {
tok->f.kind = classifyOperator(yytext, yylen);

View File

@@ -36,14 +36,7 @@ static inline int classify3(const char *s) {
if (s[0] == 'e') {
if (s[1] == 'n') {
if (s[2] == 'd') {
return T_AT_END;
}
}
}
else if (s[0] == 't') {
if (s[1] == 'r') {
if (s[2] == 'y') {
return T_AT_TRY;
return T_END;
}
}
}
@@ -55,42 +48,7 @@ static inline int classify4(const char *s) {
if (s[1] == 'e') {
if (s[2] == 'f') {
if (s[3] == 's') {
return T_AT_DEFS;
}
}
}
}
return T_ERROR;
}
static inline int classify5(const char *s) {
if (s[0] == 'c') {
if (s[1] == 'a') {
if (s[2] == 't') {
if (s[3] == 'c') {
if (s[4] == 'h') {
return T_AT_CATCH;
}
}
}
}
else if (s[1] == 'l') {
if (s[2] == 'a') {
if (s[3] == 's') {
if (s[4] == 's') {
return T_AT_CLASS;
}
}
}
}
}
else if (s[0] == 't') {
if (s[1] == 'h') {
if (s[2] == 'r') {
if (s[3] == 'o') {
if (s[4] == 'w') {
return T_AT_THROW;
}
return T_DEFS;
}
}
}
@@ -105,20 +63,7 @@ static inline int classify6(const char *s) {
if (s[3] == 'o') {
if (s[4] == 'd') {
if (s[5] == 'e') {
return T_AT_ENCODE;
}
}
}
}
}
}
else if (s[0] == 'p') {
if (s[1] == 'u') {
if (s[2] == 'b') {
if (s[3] == 'l') {
if (s[4] == 'i') {
if (s[5] == 'c') {
return T_AT_PUBLIC;
return T_ENCODE;
}
}
}
@@ -136,7 +81,7 @@ static inline int classify7(const char *s) {
if (s[4] == 'm') {
if (s[5] == 'i') {
if (s[6] == 'c') {
return T_AT_DYNAMIC;
return T_DYNAMIC;
}
}
}
@@ -151,7 +96,7 @@ static inline int classify7(const char *s) {
if (s[4] == 'l') {
if (s[5] == 'l') {
if (s[6] == 'y') {
return T_AT_FINALLY;
return T_FINALLY;
}
}
}
@@ -166,7 +111,7 @@ static inline int classify7(const char *s) {
if (s[4] == 'a') {
if (s[5] == 'g') {
if (s[6] == 'e') {
return T_AT_PACKAGE;
return T_PACKAGE;
}
}
}
@@ -179,7 +124,7 @@ static inline int classify7(const char *s) {
if (s[4] == 'a') {
if (s[5] == 't') {
if (s[6] == 'e') {
return T_AT_PRIVATE;
return T_PRIVATE;
}
}
}
@@ -199,7 +144,7 @@ static inline int classify8(const char *s) {
if (s[5] == 'n') {
if (s[6] == 'a') {
if (s[7] == 'l') {
return T_AT_OPTIONAL;
return T_OPTIONAL;
}
}
}
@@ -216,7 +161,7 @@ static inline int classify8(const char *s) {
if (s[5] == 'r') {
if (s[6] == 't') {
if (s[7] == 'y') {
return T_AT_PROPERTY;
return T_PROPERTY;
}
}
}
@@ -227,7 +172,7 @@ static inline int classify8(const char *s) {
if (s[5] == 'c') {
if (s[6] == 'o') {
if (s[7] == 'l') {
return T_AT_PROTOCOL;
return T_PROTOCOL;
}
}
}
@@ -244,7 +189,7 @@ static inline int classify8(const char *s) {
if (s[5] == 'r') {
if (s[6] == 'e') {
if (s[7] == 'd') {
return T_AT_REQUIRED;
return T_REQUIRED;
}
}
}
@@ -261,7 +206,7 @@ static inline int classify8(const char *s) {
if (s[5] == 't') {
if (s[6] == 'o') {
if (s[7] == 'r') {
return T_AT_SELECTOR;
return T_SELECTOR;
}
}
}
@@ -283,26 +228,7 @@ static inline int classify9(const char *s) {
if (s[6] == 'a') {
if (s[7] == 'c') {
if (s[8] == 'e') {
return T_AT_INTERFACE;
}
}
}
}
}
}
}
}
}
else if (s[0] == 'p') {
if (s[1] == 'r') {
if (s[2] == 'o') {
if (s[3] == 't') {
if (s[4] == 'e') {
if (s[5] == 'c') {
if (s[6] == 't') {
if (s[7] == 'e') {
if (s[8] == 'd') {
return T_AT_PROTECTED;
return T_INTERFACE;
}
}
}
@@ -326,7 +252,7 @@ static inline int classify10(const char *s) {
if (s[7] == 'i') {
if (s[8] == 'z') {
if (s[9] == 'e') {
return T_AT_SYNTHESIZE;
return T_SYNTHESIZE;
}
}
}
@@ -352,7 +278,7 @@ static inline int classify11(const char *s) {
if (s[8] == 'o') {
if (s[9] == 'r') {
if (s[10] == 'd') {
return T_AT_NOT_KEYWORD;
return T_NOT_KEYWORD;
}
}
}
@@ -380,7 +306,7 @@ static inline int classify12(const char *s) {
if (s[9] == 'z') {
if (s[10] == 'e') {
if (s[11] == 'd') {
return T_AT_SYNCHRONIZED;
return T_SYNCHRONIZED;
}
}
}
@@ -411,7 +337,7 @@ static inline int classify14(const char *s) {
if (s[11] == 'i') {
if (s[12] == 'o') {
if (s[13] == 'n') {
return T_AT_IMPLEMENTATION;
return T_IMPLEMENTATION;
}
}
}
@@ -449,7 +375,7 @@ static inline int classify19(const char *s) {
if (s[16] == 'i') {
if (s[17] == 'a') {
if (s[18] == 's') {
return T_AT_COMPATIBILITY_ALIAS;
return T_COMPATIBILITY_ALIAS;
}
}
}
@@ -476,7 +402,6 @@ int Lexer::classifyObjCAtKeyword(const char *s, int n) {
switch (n) {
case 3: return classify3(s);
case 4: return classify4(s);
case 5: return classify5(s);
case 6: return classify6(s);
case 7: return classify7(s);
case 8: return classify8(s);

View File

@@ -293,13 +293,22 @@ void Parser::skipUntilDeclaration()
case T_NAMESPACE:
case T_ASM:
case T_EXPORT:
case T_AT_CLASS:
case T_AT_INTERFACE:
case T_AT_PROTOCOL:
case T_AT_IMPLEMENTATION:
case T_AT_END:
return;
// ObjC declarations:
case T_AT:
switch (LA(2)) {
case T_CLASS:
case T_INTERFACE:
case T_PROTOCOL:
case T_IMPLEMENTATION:
case T_END:
return;
default: {
// INTENTIONAL FALL-THROUGH!
}
}
default:
if (lookAtBuiltinTypeSpecifier() || lookAtClassKey() ||
lookAtFunctionSpecifier() || lookAtStorageClassSpecifier())
@@ -352,8 +361,8 @@ bool Parser::skipUntilStatement()
case T_USING:
return true;
case T_AT_SYNCHRONIZED:
if (objCEnabled())
case T_AT:
if (objCEnabled() && LA(2) == T_SYNCHRONIZED)
return true;
default:
@@ -585,23 +594,28 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
return parseTemplateDeclaration(node);
// ObjcC++
case T_AT_CLASS:
return parseObjCClassForwardDeclaration(node);
case T_AT:
if (objCEnabled()) {
switch (LA(2)) {
case T_CLASS:
return parseObjCClassForwardDeclaration(node);
case T_AT_INTERFACE:
return parseObjCInterface(node);
case T_INTERFACE:
return parseObjCInterface(node);
case T_AT_PROTOCOL:
return parseObjCProtocol(node);
case T_PROTOCOL:
return parseObjCProtocol(node);
case T_AT_IMPLEMENTATION:
return parseObjCImplementation(node);
case T_IMPLEMENTATION:
return parseObjCImplementation(node);
case T_AT_END:
// TODO: should this be done here, or higher-up?
_translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
consumeToken();
break;
case T_END:
// TODO: should this be done here, or higher-up?
_translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
consumeToken();
break;
}
}
default: {
if (_objCEnabled && LA() == T___ATTRIBUTE__) {
@@ -609,12 +623,14 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
SpecifierListAST *attributes = 0, **attr = &attributes;
while (parseAttributeSpecifier(*attr))
attr = &(*attr)->next;
if (LA() == T_AT_INTERFACE)
return parseObjCInterface(node, attributes);
else if (LA() == T_AT_PROTOCOL)
return parseObjCProtocol(node, attributes);
else if (LA() == T_AT_PROPERTY)
return parseObjCPropertyDeclaration(node, attributes);
if (LA() == T_AT) {
if (LA(2) == T_INTERFACE)
return parseObjCInterface(node, attributes);
else if (LA(2) == T_PROTOCOL)
return parseObjCProtocol(node, attributes);
else if (LA(2) == T_PROPERTY)
return parseObjCPropertyDeclaration(node, attributes);
}
rewind(start);
}
@@ -2415,9 +2431,6 @@ bool Parser::parseStatement(StatementAST *&node)
return true;
}
case T_AT_SYNCHRONIZED:
return objCEnabled() && parseObjCSynchronizedStatement(node);
case T_Q_D:
case T_Q_Q: {
QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST;
@@ -2428,6 +2441,10 @@ bool Parser::parseStatement(StatementAST *&node)
node = ast;
} return true;
case T_AT:
return objCEnabled() && LA(2) == T_SYNCHRONIZED
&& parseObjCSynchronizedStatement(node);
default:
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
return parseLabeledStatement(node);
@@ -3470,10 +3487,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
return parseQtMethod(node);
case T_LBRACKET:
case T_AT_STRING_LITERAL:
case T_AT_ENCODE:
case T_AT_PROTOCOL:
case T_AT_SELECTOR:
case T_AT:
return parseObjCExpression(node);
default: {
@@ -3493,20 +3507,22 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
bool Parser::parseObjCExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
switch (LA()) {
case T_AT_ENCODE:
if (LA() == T_LBRACKET)
return parseObjCMessageExpression(node);
if (LA() != T_AT)
return false;
switch (LA(2)) {
case T_ENCODE:
return parseObjCEncodeExpression(node);
case T_AT_PROTOCOL:
case T_PROTOCOL:
return parseObjCProtocolExpression(node);
case T_AT_SELECTOR:
case T_SELECTOR:
return parseObjCSelectorExpression(node);
case T_LBRACKET:
return parseObjCMessageExpression(node);
case T_AT_STRING_LITERAL:
case T_STRING_LITERAL:
return parseObjCStringLiteral(node);
default:
@@ -3515,30 +3531,54 @@ bool Parser::parseObjCExpression(ExpressionAST *&node)
return false;
}
// We allow for the same kind of Objective-C string literals as clang, NOT as
// GCC. So, we/clang allow(s):
// NSLog(@"foo");
// NSLog(@
// "foo");
// NSLog(@"foo"
// "bar");
// NSLog(@"foo"
// @"bar');
//
// What we don't grok, but GCC also allows:
// NSLog(@"foo"
// @@"bar");
// NSLog(@"foo"
// "bar"@@);
bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_STRING_LITERAL)
if (LA() != T_AT || LA(2) != T_STRING_LITERAL)
return false;
StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
while (LA() == T_AT_STRING_LITERAL) {
*ast = new (_pool) StringLiteralAST;
(*ast)->literal_token = consumeToken();
ast = &(*ast)->next;
StringLiteralAST **ast = 0;
while (LA()) {
if (LA() == T_AT && LA(2) == T_STRING_LITERAL) {
*ast = new (_pool) StringLiteralAST;
(*ast)->at_token = consumeToken();
(*ast)->literal_token = consumeToken();
ast = &(*ast)->next;
} else if (LA() == T_STRING_LITERAL) {
*ast = new (_pool) StringLiteralAST;
(*ast)->literal_token = consumeToken();
ast = &(*ast)->next;
} else {
break;
}
}
node = *ast;
return true;
}
bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_SYNCHRONIZED)
if (LA() == T_AT || LA(2) != T_SYNCHRONIZED)
return false;
ObjCSynchronizedStatementAST *ast = new (_pool) ObjCSynchronizedStatementAST;
ast->at_token = consumeToken();
ast->synchronized_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
parseExpression(ast->synchronized_object);
@@ -3552,10 +3592,11 @@ bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_ENCODE)
if (LA() != T_AT || LA(2) != T_ENCODE)
return false;
ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
ast->at_token = consumeToken();
ast->encode_token = consumeToken();
parseObjCTypeName(ast->type_name);
node = ast;
@@ -3565,10 +3606,11 @@ bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_PROTOCOL)
if (LA() != T_AT || LA(2) != T_PROTOCOL)
return false;
ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST;
ast->at_token = consumeToken();
ast->protocol_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
match(T_IDENTIFIER, &ast->identifier_token);
@@ -3580,10 +3622,11 @@ bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_SELECTOR)
if (LA() != T_AT || LA(2) != T_SELECTOR)
return false;
ObjCSelectorExpressionAST *ast = new (_pool) ObjCSelectorExpressionAST;
ast->at_token = consumeToken();
ast->selector_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
@@ -4493,11 +4536,11 @@ bool Parser::lookAtObjCSelector() const
bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_CLASS)
if (LA() != T_AT || LA(2) != T_CLASS)
return false;
ObjCClassForwardDeclarationAST *ast = new (_pool) ObjCClassForwardDeclarationAST;
ast->at_token = consumeToken();
ast->class_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -4549,9 +4592,10 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
attr = &(*attr)->next;
}
if (LA() != T_AT_INTERFACE)
if (LA() != T_AT || LA(2) != T_INTERFACE)
return false;
unsigned at_token = consumeToken();
unsigned objc_interface_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -4565,6 +4609,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
ast->attribute_list = attributes;
ast->at_token = at_token;
ast->interface_token = objc_interface_token;
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
class_name->identifier_token= identifier_token;
@@ -4589,7 +4634,8 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
nextMembers = &(*nextMembers)->next;
}
match(T_AT_END, &ast->end_token);
match(T_AT, &ast->ending_at_token);
match(T_END, &ast->end_token);
node = ast;
return true;
@@ -4597,6 +4643,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
// a class interface declaration
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
ast->attribute_list = attributes;
ast->at_token = at_token;
ast->interface_token = objc_interface_token;
SimpleNameAST* class_name = new (_pool) SimpleNameAST;
class_name->identifier_token = identifier_token;
@@ -4620,7 +4667,8 @@ bool Parser::parseObjCInterface(DeclarationAST *&node,
nextMembers = &(*nextMembers)->next;
}
match(T_AT_END, &ast->end_token);
match(T_AT, &ast->ending_at_token);
match(T_END, &ast->end_token);
node = ast;
return true;
@@ -4639,9 +4687,10 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
attr = &(*attr)->next;
}
if (LA() != T_AT_PROTOCOL)
if (LA() != T_AT || LA(2) != T_PROTOCOL)
return false;
unsigned at_token = consumeToken();
unsigned protocol_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -4651,6 +4700,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
ast->attribute_list = attributes;
ast->at_token = at_token;
ast->protocol_token = protocol_token;
ast->identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
@@ -4676,6 +4726,7 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
// a protocol definition
ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
ast->attribute_list = attributes;
ast->at_token = at_token;
ast->protocol_token = protocol_token;
SimpleNameAST *name = new (_pool) SimpleNameAST;
name->identifier_token = identifier_token;
@@ -4691,7 +4742,8 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
nextMembers = &(*nextMembers)->next;
}
match(T_AT_END, &ast->end_token);
match(T_AT, &ast->ending_at_token);
match(T_END, &ast->end_token);
node = ast;
return true;
@@ -4705,9 +4757,10 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
bool Parser::parseObjCImplementation(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_IMPLEMENTATION)
if (LA() != T_AT || LA(2) != T_IMPLEMENTATION)
return false;
unsigned at_token = consumeToken();
unsigned implementation_token = consumeToken();
unsigned identifier_token = 0;
match(T_IDENTIFIER, &identifier_token);
@@ -4715,6 +4768,7 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
if (LA() == T_LPAREN) {
// a category implementation
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
ast->at_token = at_token;
ast->implementation_token = implementation_token;
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
class_name->identifier_token = identifier_token;
@@ -4727,12 +4781,14 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
match(T_RPAREN, &ast->rparen_token);
parseObjCMethodDefinitionList(ast->member_declaration_list);
match(T_AT_END, &ast->end_token);
match(T_AT, &ast->ending_at_token);
match(T_END, &ast->end_token);
node = ast;
} else {
// a class implementation
ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
ast->at_token = at_token;
ast->implementation_token = implementation_token;
SimpleNameAST *class_name = new (_pool) SimpleNameAST;
class_name->identifier_token = identifier_token;
@@ -4747,7 +4803,8 @@ bool Parser::parseObjCImplementation(DeclarationAST *&node)
parseObjClassInstanceVariables(ast->inst_vars_decl);
parseObjCMethodDefinitionList(ast->member_declaration_list);
match(T_AT_END, &ast->end_token);
match(T_AT, &ast->ending_at_token);
match(T_END, &ast->end_token);
node = ast;
}
@@ -4760,7 +4817,7 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
DEBUG_THIS_RULE();
DeclarationListAST **next = &node;
while (LA() && LA() != T_AT_END) {
while (LA() && !(LA() == T_AT && LA(2) == T_END)) {
unsigned start = cursor();
DeclarationAST *declaration = 0;
@@ -4777,26 +4834,12 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
consumeToken();
break;
case T_AT_SYNTHESIZE: {
ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
ast->synthesized_token = consumeToken();
ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
ast->property_identifier_list = last;
last->value = new (_pool) ObjCSynthesizedPropertyAST;
match(T_IDENTIFIER, &last->value->property_identifier_token);
if (LA() == T_EQUAL) {
last->value->equals_token = consumeToken();
match(T_IDENTIFIER, &last->value->alias_identifier_token);
}
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
last->next = new (_pool) ObjCSynthesizedPropertyListAST;
last = last->next;
case T_AT:
if (LA(2) == T_SYNTHESIZE) {
ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
ast->synthesized_token = consumeToken();
ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
ast->property_identifier_list = last;
last->value = new (_pool) ObjCSynthesizedPropertyAST;
match(T_IDENTIFIER, &last->value->property_identifier_token);
@@ -4805,39 +4848,52 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
match(T_IDENTIFIER, &last->value->alias_identifier_token);
}
}
match(T_SEMICOLON, &ast->semicolon_token);
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
declaration = ast;
break;
}
last->next = new (_pool) ObjCSynthesizedPropertyListAST;
last = last->next;
case T_AT_DYNAMIC: {
ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
ast->dynamic_token = consumeToken();
ast->property_identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &name->identifier_token);
ast->property_identifier_list->value = name;
last->value = new (_pool) ObjCSynthesizedPropertyAST;
match(T_IDENTIFIER, &last->value->property_identifier_token);
NameListAST *last = ast->property_identifier_list;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
if (LA() == T_EQUAL) {
last->value->equals_token = consumeToken();
last->next = new (_pool) NameListAST;
last = last->next;
name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &last->value->alias_identifier_token);
}
}
match(T_SEMICOLON, &ast->semicolon_token);
declaration = ast;
break;
} else if (LA(2) == T_DYNAMIC) {
ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
ast->dynamic_token = consumeToken();
ast->property_identifier_list = new (_pool) NameListAST;
SimpleNameAST *name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &name->identifier_token);
last->value = name;
ast->property_identifier_list->value = name;
NameListAST *last = ast->property_identifier_list;
while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA
last->next = new (_pool) NameListAST;
last = last->next;
name = new (_pool) SimpleNameAST;
match(T_IDENTIFIER, &name->identifier_token);
last->value = name;
}
match(T_SEMICOLON, &ast->semicolon_token);
declaration = ast;
break;
}
match(T_SEMICOLON, &ast->semicolon_token);
declaration = ast;
break;
}
default:
if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
parseDeclaration(declaration);
@@ -4967,22 +5023,6 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
switch (LA()) {
case T_AT_END:
return false;
case T_AT_REQUIRED:
case T_AT_OPTIONAL:
consumeToken();
return true;
case T_SEMICOLON:
consumeToken();
return true;
case T_AT_PROPERTY: {
return parseObjCPropertyDeclaration(node);
}
case T_PLUS:
case T_MINUS: {
ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
@@ -5002,6 +5042,30 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
return parseSimpleDeclaration(node, /*accept struct declarators */ true);
}
case T_AT:
switch (LA(2)) {
case T_END:
return false;
case T_REQUIRED:
case T_OPTIONAL:
// ### FIXME
consumeToken();
return true;
case T_SEMICOLON:
consumeToken();
return true;
case T_PROPERTY: {
return parseObjCPropertyDeclaration(node);
default: {
// INTENTIONAL FALL-THROUGH!
}
}
}
default: {
return parseSimpleDeclaration(node, /*accept struct declarators */ true);
} // default
@@ -5015,20 +5079,23 @@ bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
{
DEBUG_THIS_RULE();
switch (LA()) {
case T_AT_PRIVATE:
case T_AT_PROTECTED:
case T_AT_PUBLIC:
case T_AT_PACKAGE: {
ObjCVisibilityDeclarationAST *ast = new (_pool) ObjCVisibilityDeclarationAST;
ast->visibility_token = consumeToken();
node = ast;
return true;
if (LA() == T_AT) {
switch (LA(2)) {
case T_PRIVATE:
case T_PROTECTED:
case T_PUBLIC:
case T_PACKAGE: {
ObjCVisibilityDeclarationAST *ast =
new (_pool) ObjCVisibilityDeclarationAST;
ast->at_token = consumeToken();
ast->visibility_token = consumeToken();
node = ast;
return true;
}
}
default:
return parseSimpleDeclaration(node, true);
}
return parseSimpleDeclaration(node, true);
}
// objc-property-declaration ::=
@@ -5037,11 +5104,12 @@ bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes)
{
DEBUG_THIS_RULE();
if (LA() != T_AT_PROPERTY)
if (LA() != T_AT || LA(2) != T_PROPERTY)
return false;
ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST;
ast->attribute_list = attributes;
ast->at_token = consumeToken();
ast->property_token = consumeToken();
if (LA() == T_LPAREN) {

View File

@@ -218,13 +218,13 @@ int Semantic::visibilityForAccessSpecifier(int tokenKind) const
int Semantic::visibilityForObjCAccessSpecifier(int tokenKind) const
{
switch (tokenKind) {
case T_AT_PUBLIC:
case T_PUBLIC:
return Symbol::Public;
case T_AT_PROTECTED:
case T_PROTECTED:
return Symbol::Protected;
case T_AT_PRIVATE:
case T_PRIVATE:
return Symbol::Private;
case T_AT_PACKAGE:
case T_PACKAGE:
return Symbol::Package;
default:
return Symbol::Protected;

View File

@@ -59,14 +59,14 @@ static const char *token_names[] = {
("<identifier>"), ("<numeric literal>"), ("<char literal>"),
("<wide char literal>"), ("<string literal>"), ("<wide char literal>"),
("<@string literal>"), ("<angle string literal>"),
("<angle string literal>"),
("&"), ("&&"), ("&="), ("->"), ("->*"), ("^"), ("^="), (":"), ("::"),
(","), ("/"), ("/="), ("."), ("..."), (".*"), ("="), ("=="), ("!"),
("!="), (">"), (">="), (">>"), (">>="), ("{"), ("["), ("<"), ("<="),
("<<"), ("<<="), ("("), ("-"), ("-="), ("--"), ("%"), ("%="), ("|"),
("|="), ("||"), ("+"), ("+="), ("++"), ("#"), ("##"), ("?"), ("}"),
("]"), (")"), (";"), ("*"), ("*="), ("~"), ("~="),
("&"), ("&&"), ("&="), ("->"), ("->*"), ("@"), ("^"), ("^="), (":"),
("::"), (","), ("/"), ("/="), ("."), ("..."), (".*"), ("="), ("=="),
("!"), ("!="), (">"), (">="), (">>"), (">>="), ("{"), ("["), ("<"),
("<="), ("<<"), ("<<="), ("("), ("-"), ("-="), ("--"), ("%"), ("%="),
("|"), ("|="), ("||"), ("+"), ("+="), ("++"), ("#"), ("##"), ("?"),
("}"), ("]"), (")"), (";"), ("*"), ("*="), ("~"), ("~="),
("asm"), ("auto"), ("bool"), ("break"), ("case"), ("catch"), ("char"),
("class"), ("const"), ("const_cast"), ("continue"), ("default"),
@@ -84,12 +84,11 @@ static const char *token_names[] = {
// gnu
("__attribute__"), ("__typeof__"),
// objc @keywords
("@catch"), ("@class"), ("@compatibility_alias"), ("@defs"), ("@dynamic"),
("@encode"), ("@end"), ("@finally"), ("@implementation"), ("@interface"),
("@not_keyword"), ("@optional"), ("@package"), ("@private"), ("@property"),
("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
// objc keywords
("@compatibility_alias"), ("@defs"), ("@dynamic"), ("@encode"), ("@end"),
("@finally"), ("@implementation"), ("@interface"), ("@not_keyword"),
("@optional"), ("@package"), ("@property"), ("@protocol"), ("@required"),
("@selector"), ("@synchronized"), ("@synthesize"),
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"),
("Q_FOREACH"), ("Q_D"), ("Q_Q"),
@@ -124,7 +123,6 @@ const char *Token::spell() const
case T_NUMERIC_LITERAL:
case T_CHAR_LITERAL:
case T_STRING_LITERAL:
case T_AT_STRING_LITERAL:
case T_ANGLE_STRING_LITERAL:
case T_WIDE_CHAR_LITERAL:
case T_WIDE_STRING_LITERAL:

View File

@@ -69,7 +69,6 @@ enum Kind {
T_WIDE_CHAR_LITERAL,
T_STRING_LITERAL,
T_WIDE_STRING_LITERAL,
T_AT_STRING_LITERAL,
T_ANGLE_STRING_LITERAL,
T_LAST_LITERAL = T_ANGLE_STRING_LITERAL,
@@ -79,6 +78,7 @@ enum Kind {
T_AMPER_EQUAL,
T_ARROW,
T_ARROW_STAR,
T_AT,
T_CARET,
T_CARET_EQUAL,
T_COLON,
@@ -196,35 +196,28 @@ enum Kind {
T___ATTRIBUTE__,
T___TYPEOF__,
// obj c++ @ keywords
T_FIRST_OBJC_AT_KEYWORD,
// obj c keywords
T_FIRST_OBJC_KEYWORD,
T_AT_CATCH = T_FIRST_OBJC_AT_KEYWORD,
T_AT_CLASS,
T_AT_COMPATIBILITY_ALIAS,
T_AT_DEFS,
T_AT_DYNAMIC,
T_AT_ENCODE,
T_AT_END,
T_AT_FINALLY,
T_AT_IMPLEMENTATION,
T_AT_INTERFACE,
T_AT_NOT_KEYWORD,
T_AT_OPTIONAL,
T_AT_PACKAGE,
T_AT_PRIVATE,
T_AT_PROPERTY,
T_AT_PROTECTED,
T_AT_PROTOCOL,
T_AT_PUBLIC,
T_AT_REQUIRED,
T_AT_SELECTOR,
T_AT_SYNCHRONIZED,
T_AT_SYNTHESIZE,
T_AT_THROW,
T_AT_TRY,
T_COMPATIBILITY_ALIAS = T_FIRST_OBJC_KEYWORD,
T_DEFS,
T_DYNAMIC,
T_ENCODE,
T_END,
T_FINALLY,
T_IMPLEMENTATION,
T_INTERFACE,
T_NOT_KEYWORD,
T_OPTIONAL,
T_PACKAGE,
T_PROPERTY,
T_PROTOCOL,
T_REQUIRED,
T_SELECTOR,
T_SYNCHRONIZED,
T_SYNTHESIZE,
T_LAST_OBJC_AT_KEYWORD = T_AT_TRY,
T_LAST_OBJC_KEYWORD = T_SYNTHESIZE,
T_FIRST_QT_KEYWORD,
@@ -313,9 +306,6 @@ public:
{ return f.kind == T_COMMENT || f.kind == T_DOXY_COMMENT ||
f.kind == T_CPP_COMMENT || f.kind == T_CPP_DOXY_COMMENT; }
inline bool isObjCAtKeyword() const
{ return f.kind >= T_FIRST_OBJC_AT_KEYWORD && f.kind <= T_LAST_OBJC_AT_KEYWORD; }
static const char *name(int kind);
public: