diff --git a/shared/cplusplus/Lexer.cpp b/shared/cplusplus/Lexer.cpp index 56098d39f247240c42eb402c249a28af7abd792b..fcc17313b4308908b77d49e3ca029f2c4e99f9cc 100644 --- a/shared/cplusplus/Lexer.cpp +++ b/shared/cplusplus/Lexer.cpp @@ -122,6 +122,12 @@ bool Lexer::qtMocRunEnabled() const void Lexer::setQtMocRunEnabled(bool onoff) { _qtMocRunEnabled = onoff; } +bool Lexer::objcEnabled() const +{ return _objcEnabled; } + +void Lexer::setObjcEnabled(bool onoff) +{ _objcEnabled = onoff; } + bool Lexer::isIncremental() const { return _isIncremental; } @@ -548,8 +554,53 @@ void Lexer::scan_helper(Token *tok) break; default: { + if (_objcEnabled) { + if (ch == '@' && _yychar >= 'a' && _yychar <= 'z') { + const char *yytext = _currentChar; + + do { + yyinp(); + if (! isalnum(_yychar)) + break; + } while (_yychar); + + const int yylen = _currentChar - yytext; + tok->kind = classifyObjCAtKeyword(yytext, yylen); + break; + } else if (ch == '@' && _yychar == '"') { + // objc @string literals + ch = _yychar; + yyinp(); + tok->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 literals + // wide char/string literals ch = _yychar; yyinp(); diff --git a/shared/cplusplus/Lexer.h b/shared/cplusplus/Lexer.h index d9610849ab983187b471d60ca814a7d7b87fe551..84fa41073635a03157dad0b92d435f67701e8788 100644 --- a/shared/cplusplus/Lexer.h +++ b/shared/cplusplus/Lexer.h @@ -80,6 +80,9 @@ public: bool qtMocRunEnabled() const; void setQtMocRunEnabled(bool onoff); + bool objcEnabled() const; + void setObjcEnabled(bool onoff); + void scan(Token *tok); inline void operator()(Token *tok) @@ -112,6 +115,7 @@ private: void scan_helper(Token *tok); void setSource(const char *firstChar, const char *lastChar); static int classify(const char *string, int length, bool q); + static int classifyObjCAtKeyword(const char *s, int n); static int classifyOperator(const char *string, int length); inline void yyinp() @@ -143,6 +147,7 @@ private: unsigned _scanKeywords: 1; unsigned _scanAngleStringLiteralTokens: 1; unsigned _qtMocRunEnabled: 1; + unsigned _objcEnabled: 1; }; }; unsigned _currentLine; diff --git a/shared/cplusplus/Token.cpp b/shared/cplusplus/Token.cpp index c21c7b4681ee2920c2432af5cdbd1fbfef98f0d8..5ebd873dce21dac85c4ad601c197dfc40bfa4ee8 100644 --- a/shared/cplusplus/Token.cpp +++ b/shared/cplusplus/Token.cpp @@ -62,7 +62,7 @@ static const char *token_names[] = { ("<identifier>"), ("<int literal>"), ("<float literal>"), ("<char literal>"), ("<wide char literal>"), ("<string literal>"), ("<wide char literal>"), - ("<angle string literal>"), + ("<@string literal>"), ("<angle string literal>"), ("&"), ("&&"), ("&="), ("->"), ("->*"), ("^"), ("^="), (":"), ("::"), (","), ("/"), ("/="), ("."), ("..."), (".*"), ("="), ("=="), ("!"), @@ -84,8 +84,16 @@ static const char *token_names[] = { ("union"), ("unsigned"), ("using"), ("virtual"), ("void"), ("volatile"), ("wchar_t"), ("while"), + // 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"), + ("SIGNAL"), ("SLOT"), ("Q_SIGNALS"), ("Q_SLOTS") }; @@ -118,6 +126,7 @@ const char *Token::spell() const case T_FLOAT_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: diff --git a/shared/cplusplus/Token.h b/shared/cplusplus/Token.h index 826f724d2c8933c14f47e7bb830f613b85b9af71..d5b6f1a1c0eab08279942cd3bae67c78708ae394 100644 --- a/shared/cplusplus/Token.h +++ b/shared/cplusplus/Token.h @@ -73,6 +73,7 @@ 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, @@ -199,6 +200,34 @@ enum Kind { T___ATTRIBUTE__, T___TYPEOF__, + // obj c++ @ keywords + T_FIRST_OBJC_KEYWORD, + + T_AT_CATCH = T_FIRST_OBJC_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_FIRST_QT_KEYWORD, // Qt keywords diff --git a/shared/cplusplus/cplusplus.pri b/shared/cplusplus/cplusplus.pri index c3042948c14ab6dfa684e09fbf9b4d8533b8d674..041aff67be21e2e37ce249d3ea576f2c5ad3a0bd 100644 --- a/shared/cplusplus/cplusplus.pri +++ b/shared/cplusplus/cplusplus.pri @@ -54,6 +54,7 @@ SOURCES += \ $$PWD/DiagnosticClient.cpp \ $$PWD/FullySpecifiedType.cpp \ $$PWD/Keywords.cpp \ + $$PWD/ObjectiveCAtKeywords.cpp \ $$PWD/Lexer.cpp \ $$PWD/LiteralTable.cpp \ $$PWD/Literals.cpp \