diff options
author | Erik Verbruggen <erik.verbruggen@nokia.com> | 2010-02-14 14:41:51 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@nokia.com> | 2010-02-15 09:27:00 +0100 |
commit | 2a59d2ae0c889fe6e4ac50a3f110b0103f880c15 (patch) | |
tree | ff989d0d79fcee735d24bf88ef7552aa43aa1c7f /src/shared/cplusplus/Lexer.cpp | |
parent | abdd404ff5ec8539f0d3fd38139eb08ad8a03d66 (diff) | |
download | qt-creator-2a59d2ae0c889fe6e4ac50a3f110b0103f880c15.tar.gz |
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".
Diffstat (limited to 'src/shared/cplusplus/Lexer.cpp')
-rw-r--r-- | src/shared/cplusplus/Lexer.cpp | 62 |
1 files changed, 14 insertions, 48 deletions
diff --git a/src/shared/cplusplus/Lexer.cpp b/src/shared/cplusplus/Lexer.cpp index 9a71ccfa7e..f8cc188238 100644 --- a/src/shared/cplusplus/Lexer.cpp +++ b/src/shared/cplusplus/Lexer.cpp @@ -596,52 +596,11 @@ void Lexer::scan_helper(Token *tok) tok->f.kind = T_COMMA; 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; - } - } + case '@': + tok->f.kind = T_AT; + break; + default: { 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); |