tools/icheck/parser/src/shared/cplusplus/Parser.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 // Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
       
    42 //
       
    43 // Permission is hereby granted, free of charge, to any person obtaining a copy
       
    44 // of this software and associated documentation files (the "Software"), to deal
       
    45 // in the Software without restriction, including without limitation the rights
       
    46 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    47 // copies of the Software, and to permit persons to whom the Software is
       
    48 // furnished to do so, subject to the following conditions:
       
    49 //
       
    50 // The above copyright notice and this permission notice shall be included in
       
    51 // all copies or substantial portions of the Software.
       
    52 //
       
    53 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    54 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    55 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       
    56 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    57 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    58 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    59 // THE SOFTWARE.
       
    60 
       
    61 #include "Parser.h"
       
    62 #include "Token.h"
       
    63 #include "Lexer.h"
       
    64 #include "Control.h"
       
    65 #include "AST.h"
       
    66 #include "Literals.h"
       
    67 #include "ObjectiveCTypeQualifiers.h"
       
    68 #include <cstdio> // for putchar
       
    69 #ifdef ICHECK_BUILD
       
    70 #  include <QString>
       
    71 #endif
       
    72 
       
    73 #define CPLUSPLUS_NO_DEBUG_RULE
       
    74 #define MAX_EXPRESSION_DEPTH 100
       
    75 
       
    76 using namespace CPlusPlus;
       
    77 
       
    78 namespace {
       
    79 
       
    80 class DebugRule {
       
    81     const char *name;
       
    82     static int depth;
       
    83 
       
    84 public:
       
    85     DebugRule(const char *name)
       
    86         : name(name)
       
    87     {
       
    88         for (int i = 0; i < depth; ++i)
       
    89             putchar(' ');
       
    90 
       
    91         ++depth;
       
    92         printf("%s\n", name);
       
    93     }
       
    94 
       
    95     ~DebugRule()
       
    96     { --depth; }
       
    97 };
       
    98 
       
    99 int DebugRule::depth = 0;
       
   100 
       
   101 inline bool lookAtAssignmentOperator(int tokenKind)
       
   102 {
       
   103     switch (tokenKind) {
       
   104     case T_EQUAL:
       
   105     case T_AMPER_EQUAL:
       
   106     case T_CARET_EQUAL:
       
   107     case T_SLASH_EQUAL:
       
   108     case T_GREATER_GREATER_EQUAL:
       
   109     case T_LESS_LESS_EQUAL:
       
   110     case T_MINUS_EQUAL:
       
   111     case T_PERCENT_EQUAL:
       
   112     case T_PIPE_EQUAL:
       
   113     case T_PLUS_EQUAL:
       
   114     case T_STAR_EQUAL:
       
   115     case T_TILDE_EQUAL:
       
   116         return true;
       
   117     default:
       
   118         return false;
       
   119     } // switch
       
   120 }
       
   121 
       
   122 namespace Prec {
       
   123 enum {
       
   124     Unknown         = 0,
       
   125     Comma           = 1,
       
   126     Assignment      = 2,
       
   127     Conditional     = 3,
       
   128     LogicalOr       = 4,
       
   129     LogicalAnd      = 5,
       
   130     InclusiveOr     = 6,
       
   131     ExclusiveOr     = 7,
       
   132     And             = 8,
       
   133     Equality        = 9,
       
   134     Relational      = 10,
       
   135     Shift           = 11,
       
   136     Additive        = 12,
       
   137     Multiplicative  = 13,
       
   138     PointerToMember = 14
       
   139 };
       
   140 } // end of namespace Precedece
       
   141 
       
   142 inline int precedence(int tokenKind, bool templateArguments)
       
   143 {
       
   144     // ### this will/might need some tuning for C++0x
       
   145     // (see: [temp.names]p3)
       
   146     if (templateArguments && tokenKind == T_GREATER)
       
   147         return -1;
       
   148 
       
   149     if (lookAtAssignmentOperator(tokenKind))
       
   150         return Prec::Assignment;
       
   151 
       
   152     switch (tokenKind) {
       
   153     case T_COMMA:           return Prec::Comma;
       
   154     case T_QUESTION:        return Prec::Conditional;
       
   155     case T_PIPE_PIPE:       return Prec::LogicalOr;
       
   156     case T_AMPER_AMPER:     return Prec::LogicalAnd;
       
   157     case T_PIPE:            return Prec::InclusiveOr;
       
   158     case T_CARET:           return Prec::ExclusiveOr;
       
   159     case T_AMPER:           return Prec::And;
       
   160     case T_EQUAL_EQUAL:
       
   161     case T_EXCLAIM_EQUAL:   return Prec::Equality;
       
   162     case T_GREATER:
       
   163     case T_LESS:
       
   164     case T_LESS_EQUAL:
       
   165     case T_GREATER_EQUAL:   return Prec::Relational;
       
   166     case T_LESS_LESS:
       
   167     case T_GREATER_GREATER: return Prec::ExclusiveOr;
       
   168     case T_PLUS:
       
   169     case T_MINUS:           return Prec::Additive;
       
   170     case T_STAR:
       
   171     case T_SLASH:
       
   172     case T_PERCENT:         return Prec::Multiplicative;
       
   173     case T_ARROW_STAR:
       
   174     case T_DOT_STAR:        return Prec::PointerToMember;
       
   175     default:                return Prec::Unknown;
       
   176     }
       
   177 }
       
   178 
       
   179 inline bool isBinaryOperator(int tokenKind)
       
   180 { return precedence(tokenKind, false) != Prec::Unknown; }
       
   181 
       
   182 inline bool isRightAssociative(int tokenKind)
       
   183 {
       
   184     const int prec = precedence(tokenKind, false);
       
   185     return prec == Prec::Conditional || prec == Prec::Assignment;
       
   186 }
       
   187 
       
   188 } // end of anonymous namespace
       
   189 
       
   190 #ifndef CPLUSPLUS_NO_DEBUG_RULE
       
   191 #  define DEBUG_THIS_RULE() DebugRule __debug_rule__(__func__)
       
   192 #else
       
   193 #  define DEBUG_THIS_RULE() do {} while (0)
       
   194 #endif
       
   195 
       
   196 #define PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, minPrecedence) { \
       
   197     if (LA() == T_THROW) { \
       
   198         if (!parseThrowExpression(node)) \
       
   199             return false; \
       
   200     } else if (!parseCastExpression(node)) \
       
   201         return false; \
       
   202     \
       
   203     parseExpressionWithOperatorPrecedence(node, minPrecedence); \
       
   204     return true; \
       
   205 }
       
   206 
       
   207 class Parser::Rewind
       
   208 {
       
   209     Parser *_parser;
       
   210     MemoryPool::State _state;
       
   211 
       
   212 public:
       
   213     inline Rewind(Parser *parser)
       
   214         : _parser(parser) {}
       
   215 
       
   216     inline void operator()(unsigned tokenIndex)
       
   217     { rewind(tokenIndex); }
       
   218 
       
   219     inline void mark()
       
   220     { _state = _parser->_pool->state(); }
       
   221 
       
   222     inline void rewind(unsigned tokenIndex)
       
   223     {
       
   224         _parser->rewind(tokenIndex);
       
   225 
       
   226         if (_state.isValid())
       
   227             _parser->_pool->rewind(_state);
       
   228     }
       
   229 };
       
   230 
       
   231 Parser::Parser(TranslationUnit *unit)
       
   232     : _translationUnit(unit),
       
   233       _control(_translationUnit->control()),
       
   234       _pool(_translationUnit->memoryPool()),
       
   235       _tokenIndex(1),
       
   236       _templateArguments(0),
       
   237       _qtMocRunEnabled(false),
       
   238       _objCEnabled(false),
       
   239       _inFunctionBody(false),
       
   240       _inObjCImplementationContext(false),
       
   241       _expressionDepth(0)
       
   242 { }
       
   243 
       
   244 Parser::~Parser()
       
   245 { }
       
   246 
       
   247 bool Parser::qtMocRunEnabled() const
       
   248 { return _qtMocRunEnabled; }
       
   249 
       
   250 void Parser::setQtMocRunEnabled(bool onoff)
       
   251 { _qtMocRunEnabled = onoff; }
       
   252 
       
   253 bool Parser::objCEnabled() const
       
   254 { return _objCEnabled; }
       
   255 
       
   256 void Parser::setObjCEnabled(bool onoff)
       
   257 { _objCEnabled = onoff; }
       
   258 
       
   259 bool Parser::switchTemplateArguments(bool templateArguments)
       
   260 {
       
   261     bool previousTemplateArguments = _templateArguments;
       
   262     _templateArguments = templateArguments;
       
   263     return previousTemplateArguments;
       
   264 }
       
   265 
       
   266 bool Parser::blockErrors(bool block)
       
   267 { return _translationUnit->blockErrors(block); }
       
   268 
       
   269 bool Parser::skipUntil(int token)
       
   270 {
       
   271     while (int tk = LA()) {
       
   272         if (tk == token)
       
   273             return true;
       
   274 
       
   275         consumeToken();
       
   276     }
       
   277 
       
   278     return false;
       
   279 }
       
   280 
       
   281 void Parser::skipUntilDeclaration()
       
   282 {
       
   283     for (; ; consumeToken()) {
       
   284         switch (LA()) {
       
   285         case T_EOF_SYMBOL:
       
   286 
       
   287         // names
       
   288         case T_IDENTIFIER:
       
   289         case T_COLON_COLON:
       
   290         case T_TILDE:
       
   291         case T_OPERATOR:
       
   292 
       
   293         // empty declaration
       
   294         case T_SEMICOLON:
       
   295 
       
   296         // member specification
       
   297         case T_USING:
       
   298         case T_TEMPLATE:
       
   299         case T_PUBLIC:
       
   300         case T_PROTECTED:
       
   301         case T_PRIVATE:
       
   302         case T_Q_SIGNALS:
       
   303         case T_Q_SLOTS:
       
   304 
       
   305         // declarations
       
   306         case T_ENUM:
       
   307         case T_NAMESPACE:
       
   308         case T_ASM:
       
   309         case T_EXPORT:
       
   310         case T_AT_CLASS:
       
   311         case T_AT_INTERFACE:
       
   312         case T_AT_PROTOCOL:
       
   313         case T_AT_IMPLEMENTATION:
       
   314         case T_AT_END:
       
   315             return;
       
   316 
       
   317         default:
       
   318             if (lookAtBuiltinTypeSpecifier() || lookAtClassKey() ||
       
   319                 lookAtFunctionSpecifier() || lookAtStorageClassSpecifier())
       
   320                 return;
       
   321         } // switch
       
   322     }
       
   323 }
       
   324 
       
   325 bool Parser::skipUntilStatement()
       
   326 {
       
   327     while (int tk = LA()) {
       
   328         switch (tk) {
       
   329             case T_SEMICOLON:
       
   330             case T_LBRACE:
       
   331             case T_RBRACE:
       
   332             case T_CONST:
       
   333             case T_VOLATILE:
       
   334             case T_IDENTIFIER:
       
   335             case T_CASE:
       
   336             case T_DEFAULT:
       
   337             case T_IF:
       
   338             case T_SWITCH:
       
   339             case T_WHILE:
       
   340             case T_DO:
       
   341             case T_FOR:
       
   342             case T_BREAK:
       
   343             case T_CONTINUE:
       
   344             case T_RETURN:
       
   345             case T_GOTO:
       
   346             case T_TRY:
       
   347             case T_CATCH:
       
   348             case T_THROW:
       
   349             case T_CHAR:
       
   350             case T_WCHAR_T:
       
   351             case T_BOOL:
       
   352             case T_SHORT:
       
   353             case T_INT:
       
   354             case T_LONG:
       
   355             case T_SIGNED:
       
   356             case T_UNSIGNED:
       
   357             case T_FLOAT:
       
   358             case T_DOUBLE:
       
   359             case T_VOID:
       
   360             case T_CLASS:
       
   361             case T_STRUCT:
       
   362             case T_UNION:
       
   363             case T_ENUM:
       
   364             case T_COLON_COLON:
       
   365             case T_TEMPLATE:
       
   366             case T_USING:
       
   367                 return true;
       
   368 
       
   369             case T_AT_SYNCHRONIZED:
       
   370                 if (objCEnabled())
       
   371                     return true;
       
   372 
       
   373             default:
       
   374                 consumeToken();
       
   375         }
       
   376     }
       
   377 
       
   378     return false;
       
   379 }
       
   380 
       
   381 bool Parser::skip(int l, int r)
       
   382 {
       
   383     int count = 0;
       
   384 
       
   385     while (int tk = LA()) {
       
   386         if (tk == l)
       
   387             ++count;
       
   388         else if (tk == r)
       
   389             --count;
       
   390         else if (l != T_LBRACE && (tk == T_LBRACE ||
       
   391                                    tk == T_RBRACE ||
       
   392                                    tk == T_SEMICOLON))
       
   393             return false;
       
   394 
       
   395         if (count == 0)
       
   396             return true;
       
   397 
       
   398         consumeToken();
       
   399     }
       
   400 
       
   401     return false;
       
   402 }
       
   403 
       
   404 void Parser::match(int kind, unsigned *token)
       
   405 {
       
   406     if (LA() == kind)
       
   407         *token = consumeToken();
       
   408     else {
       
   409         *token = 0;
       
   410         _translationUnit->error(_tokenIndex, "expected token `%s' got `%s'",
       
   411                                 Token::name(kind), tok().spell());
       
   412     }
       
   413 }
       
   414 
       
   415 bool Parser::parseClassOrNamespaceName(NameAST *&node)
       
   416 {
       
   417     DEBUG_THIS_RULE();
       
   418     if (LA() == T_IDENTIFIER) {
       
   419         unsigned identifier_token = cursor();
       
   420 
       
   421         if (LA(2) == T_LESS && parseTemplateId(node) && LA() == T_COLON_COLON)
       
   422             return true;
       
   423 
       
   424         rewind(identifier_token);
       
   425 
       
   426         if (LA(2) == T_COLON_COLON) {
       
   427             SimpleNameAST *ast = new (_pool) SimpleNameAST;
       
   428             ast->identifier_token = consumeToken();
       
   429             node = ast;
       
   430             return true;
       
   431         }
       
   432     } else if (LA() == T_TEMPLATE) {
       
   433         unsigned template_token = consumeToken();
       
   434         if (parseTemplateId(node))
       
   435             return true;
       
   436         rewind(template_token);
       
   437     }
       
   438     return false;
       
   439 }
       
   440 
       
   441 bool Parser::parseTemplateId(NameAST *&node)
       
   442 {
       
   443     DEBUG_THIS_RULE();
       
   444 
       
   445     const unsigned start = cursor();
       
   446 
       
   447     if (LA() == T_IDENTIFIER && LA(2) == T_LESS) {
       
   448         TemplateIdAST *ast = new (_pool) TemplateIdAST;
       
   449         ast->identifier_token = consumeToken();
       
   450         ast->less_token = consumeToken();
       
   451         if (LA() == T_GREATER || parseTemplateArgumentList(
       
   452                 ast->template_argument_list)) {
       
   453             if (LA() == T_GREATER) {
       
   454                 ast->greater_token = consumeToken();
       
   455                 node = ast;
       
   456                 return true;
       
   457             }
       
   458         }
       
   459     }
       
   460 
       
   461     rewind(start);
       
   462 
       
   463     return false;
       
   464 }
       
   465 
       
   466 bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node,
       
   467                                       bool /*acceptTemplateId*/)
       
   468 {
       
   469     DEBUG_THIS_RULE();
       
   470     NestedNameSpecifierListAST **nested_name_specifier = &node;
       
   471     NameAST *class_or_namespace_name = 0;
       
   472     if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
       
   473         unsigned scope_token = consumeToken();
       
   474 
       
   475         NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST;
       
   476         name->class_or_namespace_name = class_or_namespace_name;
       
   477         name->scope_token = scope_token;
       
   478 
       
   479         *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
       
   480         nested_name_specifier = &(*nested_name_specifier)->next;
       
   481 
       
   482         while (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
       
   483             scope_token = consumeToken();
       
   484 
       
   485             name = new (_pool) NestedNameSpecifierAST;
       
   486             name->class_or_namespace_name = class_or_namespace_name;
       
   487             name->scope_token = scope_token;
       
   488 
       
   489             *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
       
   490             nested_name_specifier = &(*nested_name_specifier)->next;
       
   491         }
       
   492 
       
   493         // ### ugly hack
       
   494         rewind(scope_token);
       
   495         consumeToken();
       
   496         return true;
       
   497     }
       
   498 
       
   499     return false;
       
   500 }
       
   501 
       
   502 bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId)
       
   503 {
       
   504     DEBUG_THIS_RULE();
       
   505     unsigned start = cursor();
       
   506     if (! parseNestedNameSpecifier(name, acceptTemplateId))
       
   507         rewind(start);
       
   508     return true;
       
   509 }
       
   510 
       
   511 bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
       
   512 {
       
   513     DEBUG_THIS_RULE();
       
   514     unsigned global_scope_token = 0;
       
   515     if (LA() == T_COLON_COLON)
       
   516         global_scope_token = consumeToken();
       
   517 
       
   518     NestedNameSpecifierListAST *nested_name_specifier = 0;
       
   519     parseNestedNameSpecifierOpt(nested_name_specifier,
       
   520                                 /*acceptTemplateId=*/ true);
       
   521 
       
   522     NameAST *unqualified_name = 0;
       
   523     if (parseUnqualifiedName(unqualified_name,
       
   524                              /*acceptTemplateId=*/ acceptTemplateId || nested_name_specifier != 0)) {
       
   525         if (! global_scope_token && ! nested_name_specifier) {
       
   526             node = unqualified_name;
       
   527             return true;
       
   528         }
       
   529 
       
   530         QualifiedNameAST *ast = new (_pool) QualifiedNameAST;
       
   531         ast->global_scope_token = global_scope_token;
       
   532         ast->nested_name_specifier_list = nested_name_specifier;
       
   533         ast->unqualified_name = unqualified_name;
       
   534         node = ast;
       
   535         return true;
       
   536     }
       
   537 
       
   538     return false;
       
   539 }
       
   540 
       
   541 bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
       
   542 {
       
   543     DEBUG_THIS_RULE();
       
   544     TranslationUnitAST *ast = new (_pool) TranslationUnitAST;
       
   545     DeclarationListAST **decl = &ast->declaration_list;
       
   546 
       
   547     while (LA()) {
       
   548         unsigned start_declaration = cursor();
       
   549 
       
   550         DeclarationAST *declaration = 0;
       
   551 
       
   552         if (parseDeclaration(declaration)) {
       
   553             *decl = new (_pool) DeclarationListAST;
       
   554             (*decl)->value = declaration;
       
   555             decl = &(*decl)->next;
       
   556         } else {
       
   557             _translationUnit->error(start_declaration, "expected a declaration");
       
   558             rewind(start_declaration + 1);
       
   559             skipUntilDeclaration();
       
   560         }
       
   561 
       
   562         _templateArgumentList.clear();
       
   563     }
       
   564 
       
   565     node = ast;
       
   566     return true;
       
   567 }
       
   568 
       
   569 bool Parser::parseEmptyDeclaration(DeclarationAST *&node)
       
   570 {
       
   571     DEBUG_THIS_RULE();
       
   572     if (LA() == T_SEMICOLON) {
       
   573         EmptyDeclarationAST *ast = new (_pool) EmptyDeclarationAST;
       
   574         ast->semicolon_token = consumeToken();
       
   575         node = ast;
       
   576         return true;
       
   577     }
       
   578     return false;
       
   579 }
       
   580 
       
   581 bool Parser::parseDeclaration(DeclarationAST *&node)
       
   582 {
       
   583     DEBUG_THIS_RULE();
       
   584     switch (LA()) {
       
   585     case T_SEMICOLON:
       
   586         return parseEmptyDeclaration(node);
       
   587 
       
   588     case T_NAMESPACE:
       
   589         return parseNamespace(node);
       
   590 
       
   591     case T_USING:
       
   592         return parseUsing(node);
       
   593 
       
   594     case T_ASM:
       
   595         return parseAsmDefinition(node);
       
   596 
       
   597     case T_TEMPLATE:
       
   598     case T_EXPORT:
       
   599         return parseTemplateDeclaration(node);
       
   600 
       
   601     // ObjcC++
       
   602     case T_AT_CLASS:
       
   603         return parseObjCClassForwardDeclaration(node);
       
   604 
       
   605     case T_AT_INTERFACE:
       
   606         return parseObjCInterface(node);
       
   607 
       
   608     case T_AT_PROTOCOL:
       
   609         return parseObjCProtocol(node);
       
   610 
       
   611     case T_AT_IMPLEMENTATION:
       
   612         return parseObjCImplementation(node);
       
   613 
       
   614     case T_AT_END:
       
   615         // TODO: should this be done here, or higher-up?
       
   616         _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
       
   617         consumeToken();
       
   618         break;
       
   619 
       
   620     default: {
       
   621         if (_objCEnabled && LA() == T___ATTRIBUTE__) {
       
   622             const unsigned start = cursor();
       
   623             SpecifierListAST *attributes = 0, **attr = &attributes;
       
   624             while (parseAttributeSpecifier(*attr))
       
   625                 attr = &(*attr)->next;
       
   626             if (LA() == T_AT_INTERFACE)
       
   627                 return parseObjCInterface(node, attributes);
       
   628             else if (LA() == T_AT_PROTOCOL)
       
   629                 return parseObjCProtocol(node, attributes);
       
   630             else if (LA() == T_AT_PROPERTY)
       
   631                 return parseObjCPropertyDeclaration(node, attributes);
       
   632             rewind(start);
       
   633         }
       
   634 
       
   635         if (LA() == T_EXTERN && LA(2) == T_TEMPLATE)
       
   636             return parseTemplateDeclaration(node);
       
   637         else if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL)
       
   638             return parseLinkageSpecification(node);
       
   639         else
       
   640             return parseSimpleDeclaration(node);
       
   641     }   break; // default
       
   642 
       
   643     } // end switch
       
   644 
       
   645     return false;
       
   646 }
       
   647 
       
   648 bool Parser::parseLinkageSpecification(DeclarationAST *&node)
       
   649 {
       
   650     DEBUG_THIS_RULE();
       
   651     if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
       
   652         LinkageSpecificationAST *ast = new (_pool) LinkageSpecificationAST;
       
   653         ast->extern_token = consumeToken();
       
   654         ast->extern_type_token = consumeToken();
       
   655 
       
   656         if (LA() == T_LBRACE)
       
   657             parseLinkageBody(ast->declaration);
       
   658         else
       
   659             parseDeclaration(ast->declaration);
       
   660 
       
   661         node = ast;
       
   662         return true;
       
   663     }
       
   664 
       
   665     return false;
       
   666 }
       
   667 
       
   668 bool Parser::parseLinkageBody(DeclarationAST *&node)
       
   669 {
       
   670     DEBUG_THIS_RULE();
       
   671     if (LA() == T_LBRACE) {
       
   672         LinkageBodyAST *ast = new (_pool) LinkageBodyAST;
       
   673         ast->lbrace_token = consumeToken();
       
   674         DeclarationListAST **declaration_ptr = &ast->declaration_list;
       
   675 
       
   676         while (int tk = LA()) {
       
   677             if (tk == T_RBRACE)
       
   678                 break;
       
   679 
       
   680             unsigned start_declaration = cursor();
       
   681             DeclarationAST *declaration = 0;
       
   682             if (parseDeclaration(declaration)) {
       
   683                 *declaration_ptr = new (_pool) DeclarationListAST;
       
   684                 (*declaration_ptr)->value = declaration;
       
   685                 declaration_ptr = &(*declaration_ptr)->next;
       
   686             } else {
       
   687                 _translationUnit->error(start_declaration, "expected a declaration");
       
   688                 rewind(start_declaration + 1);
       
   689                 skipUntilDeclaration();
       
   690             }
       
   691 
       
   692             _templateArgumentList.clear();
       
   693         }
       
   694         match(T_RBRACE, &ast->rbrace_token);
       
   695         node = ast;
       
   696         return true;
       
   697     }
       
   698     return false;
       
   699 }
       
   700 
       
   701 // ### rename parseNamespaceAliarOrDeclaration?
       
   702 bool Parser::parseNamespace(DeclarationAST *&node)
       
   703 {
       
   704     DEBUG_THIS_RULE();
       
   705     if (LA() != T_NAMESPACE)
       
   706         return false;
       
   707 
       
   708     unsigned namespace_token = consumeToken();
       
   709 
       
   710     if (LA() == T_IDENTIFIER && LA(2) == T_EQUAL) {
       
   711         NamespaceAliasDefinitionAST *ast =
       
   712                 new (_pool) NamespaceAliasDefinitionAST;
       
   713         ast->namespace_token = namespace_token;
       
   714         ast->namespace_name_token = consumeToken();
       
   715         ast->equal_token = consumeToken();
       
   716         parseName(ast->name);
       
   717         match(T_SEMICOLON, &ast->semicolon_token);
       
   718         node = ast;
       
   719         return true;
       
   720     }
       
   721 
       
   722     NamespaceAST *ast = new (_pool) NamespaceAST;
       
   723     ast->namespace_token = namespace_token;
       
   724     if (LA() == T_IDENTIFIER)
       
   725         ast->identifier_token = consumeToken();
       
   726     SpecifierListAST **attr_ptr = &ast->attribute_list;
       
   727     while (LA() == T___ATTRIBUTE__) {
       
   728         parseAttributeSpecifier(*attr_ptr);
       
   729         attr_ptr = &(*attr_ptr)->next;
       
   730     }
       
   731     if (LA() == T_LBRACE)
       
   732         parseLinkageBody(ast->linkage_body);
       
   733     node = ast;
       
   734     return true;
       
   735 }
       
   736 
       
   737 bool Parser::parseUsing(DeclarationAST *&node)
       
   738 {
       
   739     DEBUG_THIS_RULE();
       
   740     if (LA() != T_USING)
       
   741         return false;
       
   742 
       
   743     if (LA(2) == T_NAMESPACE)
       
   744         return parseUsingDirective(node);
       
   745 
       
   746     UsingAST *ast = new (_pool) UsingAST;
       
   747     ast->using_token = consumeToken();
       
   748 
       
   749     if (LA() == T_TYPENAME)
       
   750         ast->typename_token = consumeToken();
       
   751 
       
   752     parseName(ast->name);
       
   753     match(T_SEMICOLON, &ast->semicolon_token);
       
   754     node = ast;
       
   755     return true;
       
   756 }
       
   757 
       
   758 bool Parser::parseUsingDirective(DeclarationAST *&node)
       
   759 {
       
   760     DEBUG_THIS_RULE();
       
   761     if (LA() == T_USING && LA(2) == T_NAMESPACE) {
       
   762         UsingDirectiveAST *ast = new (_pool) UsingDirectiveAST;
       
   763         ast->using_token = consumeToken();
       
   764         ast->namespace_token = consumeToken();
       
   765         if (! parseName(ast->name))
       
   766             _translationUnit->warning(cursor(), "expected `namespace name' before `%s'",
       
   767                                       tok().spell());
       
   768         match(T_SEMICOLON, &ast->semicolon_token);
       
   769         node = ast;
       
   770         return true;
       
   771     }
       
   772     return false;
       
   773 }
       
   774 
       
   775 bool Parser::parseConversionFunctionId(NameAST *&node)
       
   776 {
       
   777     DEBUG_THIS_RULE();
       
   778     if (LA() != T_OPERATOR)
       
   779         return false;
       
   780     unsigned operator_token = consumeToken();
       
   781     SpecifierListAST *type_specifier = 0;
       
   782     if (! parseTypeSpecifier(type_specifier)) {
       
   783         return false;
       
   784     }
       
   785     PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
       
   786     while (parsePtrOperator(*ptr_operators_tail))
       
   787         ptr_operators_tail = &(*ptr_operators_tail)->next;
       
   788 
       
   789     ConversionFunctionIdAST *ast = new (_pool) ConversionFunctionIdAST;
       
   790     ast->operator_token = operator_token;
       
   791     ast->type_specifier_list = type_specifier;
       
   792     ast->ptr_operator_list = ptr_operators;
       
   793     node = ast;
       
   794     return true;
       
   795 }
       
   796 
       
   797 bool Parser::parseOperatorFunctionId(NameAST *&node)
       
   798 {
       
   799     DEBUG_THIS_RULE();
       
   800     if (LA() != T_OPERATOR)
       
   801         return false;
       
   802     unsigned operator_token = consumeToken();
       
   803 
       
   804     OperatorAST *op = 0;
       
   805     if (! parseOperator(op))
       
   806         return false;
       
   807 
       
   808     OperatorFunctionIdAST *ast = new (_pool) OperatorFunctionIdAST;
       
   809     ast->operator_token = operator_token;
       
   810     ast->op = op;
       
   811     node = ast;
       
   812     return true;
       
   813 }
       
   814 
       
   815 Parser::TemplateArgumentListEntry *Parser::templateArgumentListEntry(unsigned tokenIndex)
       
   816 {
       
   817     std::map<unsigned, TemplateArgumentListEntry>::iterator it =_templateArgumentList.find(tokenIndex);
       
   818     if (it != _templateArgumentList.end())
       
   819         return &it->second;
       
   820 
       
   821     return 0;
       
   822 }
       
   823 
       
   824 bool Parser::parseTemplateArgumentList(TemplateArgumentListAST *&node)
       
   825 {
       
   826     if (TemplateArgumentListEntry *entry = templateArgumentListEntry(cursor())) {
       
   827         rewind(entry->cursor);
       
   828         node = entry->ast;
       
   829         return entry->ast != 0;
       
   830     }
       
   831 
       
   832     unsigned start = cursor();
       
   833 
       
   834     DEBUG_THIS_RULE();
       
   835     TemplateArgumentListAST **template_argument_ptr = &node;
       
   836     ExpressionAST *template_argument = 0;
       
   837     if (parseTemplateArgument(template_argument)) {
       
   838         *template_argument_ptr = new (_pool) TemplateArgumentListAST;
       
   839         (*template_argument_ptr)->value = template_argument;
       
   840         template_argument_ptr = &(*template_argument_ptr)->next;
       
   841         while (LA() == T_COMMA) {
       
   842             consumeToken(); // consume T_COMMA
       
   843 
       
   844             if (parseTemplateArgument(template_argument)) {
       
   845                 *template_argument_ptr = new (_pool) TemplateArgumentListAST;
       
   846                 (*template_argument_ptr)->value = template_argument;
       
   847                 template_argument_ptr = &(*template_argument_ptr)->next;
       
   848             }
       
   849         }
       
   850 
       
   851         _templateArgumentList.insert(std::make_pair(cursor(), TemplateArgumentListEntry(start, cursor(), node)));
       
   852         return true;
       
   853     }
       
   854 
       
   855     _templateArgumentList.insert(std::make_pair(cursor(), TemplateArgumentListEntry(start, cursor(), 0)));
       
   856 
       
   857     return false;
       
   858 }
       
   859 
       
   860 bool Parser::parseAsmDefinition(DeclarationAST *&node)
       
   861 {
       
   862     DEBUG_THIS_RULE();
       
   863     if (LA() != T_ASM)
       
   864         return false;
       
   865 
       
   866     AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST;
       
   867     ast->asm_token = consumeToken();
       
   868 
       
   869     if (LA() == T_VOLATILE)
       
   870         ast->volatile_token = consumeToken();
       
   871 
       
   872     match(T_LPAREN, &ast->lparen_token);
       
   873     unsigned string_literal_token = 0;
       
   874     match(T_STRING_LITERAL, &string_literal_token);
       
   875     while (LA() == T_STRING_LITERAL) {
       
   876         consumeToken();
       
   877     }
       
   878     if (LA() == T_COLON) {
       
   879         consumeToken(); // skip T_COLON
       
   880         parseAsmOperandList();
       
   881         if (LA() == T_COLON) {
       
   882             consumeToken();
       
   883             parseAsmOperandList();
       
   884             if (LA() == T_COLON) {
       
   885                 consumeToken();
       
   886                 parseAsmClobberList();
       
   887             }
       
   888         } else if (LA() == T_COLON_COLON) {
       
   889             consumeToken();
       
   890             parseAsmClobberList();
       
   891         }
       
   892     } else if (LA() == T_COLON_COLON) {
       
   893         consumeToken();
       
   894         parseAsmClobberList();
       
   895     }
       
   896     match(T_RPAREN, &ast->rparen_token);
       
   897     match(T_SEMICOLON, &ast->semicolon_token);
       
   898     node = ast;
       
   899     return true;
       
   900 }
       
   901 
       
   902 bool Parser::parseAsmOperandList()
       
   903 {
       
   904     DEBUG_THIS_RULE();
       
   905     if (LA() != T_STRING_LITERAL)
       
   906         return true;
       
   907 
       
   908     if (parseAsmOperand()) {
       
   909         while (LA() == T_COMMA) {
       
   910             consumeToken();
       
   911             parseAsmOperand();
       
   912         }
       
   913         return true;
       
   914     }
       
   915 
       
   916     return false;
       
   917 }
       
   918 
       
   919 bool Parser::parseAsmOperand()
       
   920 {
       
   921     DEBUG_THIS_RULE();
       
   922     unsigned string_literal_token = 0;
       
   923     match(T_STRING_LITERAL, &string_literal_token);
       
   924 
       
   925     if (LA() == T_LBRACKET) {
       
   926         /*unsigned lbracket_token = */ consumeToken();
       
   927         match(T_STRING_LITERAL, &string_literal_token);
       
   928         unsigned rbracket_token = 0;
       
   929         match(T_RBRACKET, &rbracket_token);
       
   930     }
       
   931 
       
   932     unsigned lparen_token = 0, rparen_token = 0;
       
   933     match(T_LPAREN, &lparen_token);
       
   934     ExpressionAST *expression = 0;
       
   935     parseExpression(expression);
       
   936     match(T_RPAREN, &rparen_token);
       
   937     return true;
       
   938 }
       
   939 
       
   940 bool Parser::parseAsmClobberList()
       
   941 {
       
   942     DEBUG_THIS_RULE();
       
   943     if (LA() != T_STRING_LITERAL)
       
   944         return false;
       
   945 
       
   946     unsigned string_literal_token = consumeToken();
       
   947 
       
   948     while (LA() == T_COMMA) {
       
   949         consumeToken();
       
   950         match(T_STRING_LITERAL, &string_literal_token);
       
   951     }
       
   952 
       
   953     return true;
       
   954 }
       
   955 
       
   956 bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
       
   957 {
       
   958     DEBUG_THIS_RULE();
       
   959     if (! (LA(1) == T_TEMPLATE || ((LA(1) == T_EXPORT || LA(1) == T_EXTERN)
       
   960             && LA(2) == T_TEMPLATE)))
       
   961         return false;
       
   962 
       
   963     TemplateDeclarationAST *ast = new (_pool) TemplateDeclarationAST;
       
   964 
       
   965     if (LA() == T_EXPORT || LA() == T_EXPORT)
       
   966         ast->export_token = consumeToken();
       
   967 
       
   968     ast->template_token = consumeToken();
       
   969 
       
   970     if (LA() == T_LESS) {
       
   971         ast->less_token = consumeToken();
       
   972         if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list))
       
   973             match(T_GREATER, &ast->greater_token);
       
   974     }
       
   975 
       
   976     parseDeclaration(ast->declaration);
       
   977     node = ast;
       
   978     return true;
       
   979 }
       
   980 
       
   981 bool Parser::parseOperator(OperatorAST *&node) // ### FIXME
       
   982 {
       
   983     DEBUG_THIS_RULE();
       
   984     OperatorAST *ast = new (_pool) OperatorAST;
       
   985 
       
   986     switch (LA()) {
       
   987     case T_NEW:
       
   988     case T_DELETE: {
       
   989         ast->op_token = consumeToken();
       
   990         if (LA() == T_LBRACKET) {
       
   991             ast->open_token = consumeToken();
       
   992             match(T_RBRACKET, &ast->close_token);
       
   993         }
       
   994     } break;
       
   995 
       
   996     case T_PLUS:
       
   997     case T_MINUS:
       
   998     case T_STAR:
       
   999     case T_SLASH:
       
  1000     case T_PERCENT:
       
  1001     case T_CARET:
       
  1002     case T_AMPER:
       
  1003     case T_PIPE:
       
  1004     case T_TILDE:
       
  1005     case T_EXCLAIM:
       
  1006     case T_LESS:
       
  1007     case T_GREATER:
       
  1008     case T_COMMA:
       
  1009     case T_AMPER_EQUAL:
       
  1010     case T_CARET_EQUAL:
       
  1011     case T_SLASH_EQUAL:
       
  1012     case T_EQUAL:
       
  1013     case T_EQUAL_EQUAL:
       
  1014     case T_EXCLAIM_EQUAL:
       
  1015     case T_GREATER_EQUAL:
       
  1016     case T_GREATER_GREATER_EQUAL:
       
  1017     case T_LESS_EQUAL:
       
  1018     case T_LESS_LESS_EQUAL:
       
  1019     case T_MINUS_EQUAL:
       
  1020     case T_PERCENT_EQUAL:
       
  1021     case T_PIPE_EQUAL:
       
  1022     case T_PLUS_EQUAL:
       
  1023     case T_STAR_EQUAL:
       
  1024     case T_TILDE_EQUAL:
       
  1025     case T_LESS_LESS:
       
  1026     case T_GREATER_GREATER:
       
  1027     case T_AMPER_AMPER:
       
  1028     case T_PIPE_PIPE:
       
  1029     case T_PLUS_PLUS:
       
  1030     case T_MINUS_MINUS:
       
  1031     case T_ARROW_STAR:
       
  1032     case T_DOT_STAR:
       
  1033     case T_ARROW:
       
  1034         ast->op_token = consumeToken();
       
  1035         break;
       
  1036 
       
  1037     default:
       
  1038         if (LA() == T_LPAREN && LA(2) == T_RPAREN) {
       
  1039             ast->op_token = ast->open_token = consumeToken();
       
  1040             ast->close_token = consumeToken();
       
  1041         } else if (LA() == T_LBRACKET && LA(2) == T_RBRACKET) {
       
  1042             ast->op_token = ast->open_token = consumeToken();
       
  1043             ast->close_token = consumeToken();
       
  1044         } else {
       
  1045             return false;
       
  1046         }
       
  1047     }
       
  1048 
       
  1049     node = ast;
       
  1050     return true;
       
  1051 }
       
  1052 
       
  1053 bool Parser::parseCvQualifiers(SpecifierListAST *&node)
       
  1054 {
       
  1055     DEBUG_THIS_RULE();
       
  1056 
       
  1057     unsigned start = cursor();
       
  1058 
       
  1059     SpecifierListAST **ast = &node;
       
  1060     while (*ast)
       
  1061         ast = &(*ast)->next;
       
  1062 
       
  1063     while (int tk = LA()) {
       
  1064         if (tk == T_CONST || tk == T_VOLATILE) {
       
  1065             SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
       
  1066             spec->specifier_token = consumeToken();
       
  1067             *ast = new (_pool) SpecifierListAST(spec);
       
  1068             ast = &(*ast)->next;
       
  1069         } else if(LA() == T___ATTRIBUTE__) {
       
  1070             parseAttributeSpecifier(*ast);
       
  1071             ast = &(*ast)->next;
       
  1072         } else {
       
  1073             break;
       
  1074         }
       
  1075     }
       
  1076 
       
  1077     return start != cursor();
       
  1078 }
       
  1079 
       
  1080 bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
       
  1081 {
       
  1082     DEBUG_THIS_RULE();
       
  1083     if (LA() == T_AMPER) {
       
  1084         ReferenceAST *ast = new (_pool) ReferenceAST;
       
  1085         ast->amp_token = consumeToken();
       
  1086         node = new (_pool) PtrOperatorListAST(ast);
       
  1087         return true;
       
  1088     } else if (LA() == T_STAR) {
       
  1089         PointerAST *ast = new (_pool) PointerAST;
       
  1090         ast->star_token = consumeToken();
       
  1091         parseCvQualifiers(ast->cv_qualifier_list);
       
  1092         node = new (_pool) PtrOperatorListAST(ast);
       
  1093         return true;
       
  1094     } else if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER) {
       
  1095         unsigned scope_or_identifier_token = cursor();
       
  1096 
       
  1097         unsigned global_scope_token = 0;
       
  1098         if (LA() == T_COLON_COLON)
       
  1099             global_scope_token = consumeToken();
       
  1100 
       
  1101         NestedNameSpecifierListAST *nested_name_specifiers = 0;
       
  1102         bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true);
       
  1103         if (has_nested_name_specifier && LA() == T_STAR) {
       
  1104             PointerToMemberAST *ast = new (_pool) PointerToMemberAST;
       
  1105             ast->global_scope_token = global_scope_token;
       
  1106             ast->nested_name_specifier_list = nested_name_specifiers;
       
  1107             ast->star_token = consumeToken();
       
  1108             parseCvQualifiers(ast->cv_qualifier_list);
       
  1109             node = new (_pool) PtrOperatorListAST(ast);
       
  1110             return true;
       
  1111         }
       
  1112         rewind(scope_or_identifier_token);
       
  1113     }
       
  1114     return false;
       
  1115 }
       
  1116 
       
  1117 bool Parser::parseTemplateArgument(ExpressionAST *&node)
       
  1118 {
       
  1119     DEBUG_THIS_RULE();
       
  1120     unsigned start = cursor();
       
  1121     if (parseTypeId(node) && (LA() == T_COMMA || LA() == T_GREATER))
       
  1122         return true;
       
  1123 
       
  1124     rewind(start);
       
  1125     bool previousTemplateArguments = switchTemplateArguments(true);
       
  1126     bool parsed = parseLogicalOrExpression(node);
       
  1127     (void) switchTemplateArguments(previousTemplateArguments);
       
  1128     return parsed;
       
  1129 }
       
  1130 
       
  1131 bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq,
       
  1132                                    bool onlyTypeSpecifiers,
       
  1133                                    bool simplified)
       
  1134 {
       
  1135     DEBUG_THIS_RULE();
       
  1136     bool has_type_specifier = false;
       
  1137     NameAST *named_type_specifier = 0;
       
  1138     SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq;
       
  1139     for (;;) {
       
  1140         if (lookAtCVQualifier()) {
       
  1141             SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
       
  1142             spec->specifier_token = consumeToken();
       
  1143             *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
       
  1144             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  1145         } else if (! onlyTypeSpecifiers && lookAtStorageClassSpecifier()) {
       
  1146             SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
       
  1147             spec->specifier_token = consumeToken();
       
  1148             *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
       
  1149             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  1150         } else if (! named_type_specifier && lookAtBuiltinTypeSpecifier()) {
       
  1151             parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr);
       
  1152             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  1153             has_type_specifier = true;
       
  1154         } else if (! has_type_specifier && (LA() == T_COLON_COLON ||
       
  1155                                             LA() == T_IDENTIFIER)) {
       
  1156             if (! parseName(named_type_specifier))
       
  1157                 return false;
       
  1158             NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST;
       
  1159             spec->name = named_type_specifier;
       
  1160             *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
       
  1161             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  1162             has_type_specifier = true;
       
  1163         } else if (! simplified && ! has_type_specifier && (LA() == T_TYPENAME ||
       
  1164                                                             LA() == T_ENUM     ||
       
  1165                                                             lookAtClassKey())) {
       
  1166             unsigned startOfElaboratedTypeSpecifier = cursor();
       
  1167             if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
       
  1168                 _translationUnit->error(startOfElaboratedTypeSpecifier,
       
  1169                                         "expected an elaborated type specifier");
       
  1170                 break;
       
  1171             }
       
  1172             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  1173             has_type_specifier = true;
       
  1174         } else
       
  1175             break;
       
  1176     }
       
  1177 
       
  1178     return decl_specifier_seq != 0;
       
  1179 }
       
  1180 
       
  1181 bool Parser::parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node)
       
  1182 {
       
  1183     DEBUG_THIS_RULE();
       
  1184     unsigned start = cursor();
       
  1185     bool blocked = blockErrors(true);
       
  1186     if (parseDeclarator(node)) {
       
  1187         blockErrors(blocked);
       
  1188         return true;
       
  1189     }
       
  1190     blockErrors(blocked);
       
  1191     rewind(start);
       
  1192     return parseAbstractDeclarator(node);
       
  1193 }
       
  1194 
       
  1195 bool Parser::parseCoreDeclarator(DeclaratorAST *&node)
       
  1196 {
       
  1197     DEBUG_THIS_RULE();
       
  1198     unsigned start = cursor();
       
  1199     SpecifierListAST *attributes = 0;
       
  1200     SpecifierListAST **attribute_ptr = &attributes;
       
  1201     while (LA() == T___ATTRIBUTE__) {
       
  1202         parseAttributeSpecifier(*attribute_ptr);
       
  1203         attribute_ptr = &(*attribute_ptr)->next;
       
  1204     }
       
  1205 
       
  1206     PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
       
  1207     while (parsePtrOperator(*ptr_operators_tail))
       
  1208         ptr_operators_tail = &(*ptr_operators_tail)->next;
       
  1209 
       
  1210     if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER || LA() == T_TILDE
       
  1211             || LA() == T_OPERATOR) {
       
  1212         NameAST *name = 0;
       
  1213         if (parseName(name)) {
       
  1214             DeclaratorIdAST *declarator_id = new (_pool) DeclaratorIdAST;
       
  1215             declarator_id->name = name;
       
  1216             DeclaratorAST *ast = new (_pool) DeclaratorAST;
       
  1217             ast->attribute_list = attributes;
       
  1218             ast->ptr_operator_list = ptr_operators;
       
  1219             ast->core_declarator = declarator_id;
       
  1220             node = ast;
       
  1221             return true;
       
  1222         }
       
  1223     } else if (LA() == T_LPAREN) {
       
  1224         if (attributes)
       
  1225             _translationUnit->warning(attributes->firstToken(), "unexpected attribtues");
       
  1226 
       
  1227         unsigned lparen_token = consumeToken();
       
  1228         DeclaratorAST *declarator = 0;
       
  1229         if (parseDeclarator(declarator) && LA() == T_RPAREN) {
       
  1230             NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
       
  1231             nested_declarator->lparen_token = lparen_token;
       
  1232             nested_declarator->declarator = declarator;
       
  1233             nested_declarator->rparen_token = consumeToken();
       
  1234             DeclaratorAST *ast = new (_pool) DeclaratorAST;
       
  1235             ast->ptr_operator_list = ptr_operators;
       
  1236             ast->core_declarator = nested_declarator;
       
  1237             node = ast;
       
  1238             return true;
       
  1239         }
       
  1240     }
       
  1241     rewind(start);
       
  1242     return false;
       
  1243 }
       
  1244 
       
  1245 bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer)
       
  1246 {
       
  1247     DEBUG_THIS_RULE();
       
  1248     if (! parseCoreDeclarator(node))
       
  1249         return false;
       
  1250 
       
  1251     PostfixDeclaratorListAST **postfix_ptr = &node->postfix_declarator_list;
       
  1252 
       
  1253     for (;;) {
       
  1254         unsigned startOfPostDeclarator = cursor();
       
  1255 
       
  1256         if (LA() == T_LPAREN) {
       
  1257             if (stopAtCppInitializer) {
       
  1258                 unsigned lparen_token = cursor();
       
  1259                 ExpressionAST *initializer = 0;
       
  1260 
       
  1261                 bool blocked = blockErrors(true);
       
  1262                 if (parseInitializer(initializer, &node->equals_token)) {
       
  1263                     if (NestedExpressionAST *expr = initializer->asNestedExpression()) {
       
  1264                         if (expr->expression && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) {
       
  1265                             rewind(lparen_token);
       
  1266 
       
  1267                             // check for ambiguous declarators.
       
  1268 
       
  1269                             consumeToken();
       
  1270                             ParameterDeclarationClauseAST *parameter_declaration_clause = 0;
       
  1271                             if (parseParameterDeclarationClause(parameter_declaration_clause) && LA() == T_RPAREN) {
       
  1272                                 unsigned rparen_token = consumeToken();
       
  1273 
       
  1274                                 FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
       
  1275                                 ast->lparen_token = lparen_token;
       
  1276                                 ast->parameters = parameter_declaration_clause;
       
  1277                                 ast->as_cpp_initializer = initializer;
       
  1278                                 ast->rparen_token = rparen_token;
       
  1279                                 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
       
  1280                                 postfix_ptr = &(*postfix_ptr)->next;
       
  1281 
       
  1282                                 blockErrors(blocked);
       
  1283                                 return true;
       
  1284                             }
       
  1285 
       
  1286 
       
  1287                             blockErrors(blocked);
       
  1288                             rewind(lparen_token);
       
  1289                             return true;
       
  1290                         }
       
  1291                     }
       
  1292                 }
       
  1293 
       
  1294                 blockErrors(blocked);
       
  1295                 rewind(lparen_token);
       
  1296             }
       
  1297 
       
  1298             FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
       
  1299             ast->lparen_token = consumeToken();
       
  1300             parseParameterDeclarationClause(ast->parameters);
       
  1301             if (LA() != T_RPAREN) {
       
  1302                 rewind(startOfPostDeclarator);
       
  1303                 break;
       
  1304             }
       
  1305 
       
  1306             ast->rparen_token = consumeToken();
       
  1307             parseCvQualifiers(ast->cv_qualifier_list);
       
  1308             parseExceptionSpecification(ast->exception_specification);
       
  1309             *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
       
  1310             postfix_ptr = &(*postfix_ptr)->next;
       
  1311         } else if (LA() == T_LBRACKET) {
       
  1312             ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST;
       
  1313             ast->lbracket_token = consumeToken();
       
  1314             if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) {
       
  1315                 match(T_RBRACKET, &ast->rbracket_token);
       
  1316             }
       
  1317             *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
       
  1318             postfix_ptr = &(*postfix_ptr)->next;
       
  1319         } else
       
  1320             break;
       
  1321     }
       
  1322 
       
  1323     if (LA() == T___ASM__ && LA(2) == T_LPAREN) { // ### store the asm specifier in the AST
       
  1324         consumeToken(); // skip __asm__
       
  1325         consumeToken(); // skip T_LPAREN
       
  1326 
       
  1327         if (skipUntil(T_RPAREN))
       
  1328             consumeToken(); // skip T_RPAREN
       
  1329     }
       
  1330 
       
  1331     SpecifierListAST **spec_ptr = &node->post_attribute_list;
       
  1332     while (LA() == T___ATTRIBUTE__) {
       
  1333         parseAttributeSpecifier(*spec_ptr);
       
  1334         spec_ptr = &(*spec_ptr)->next;
       
  1335     }
       
  1336 
       
  1337     return true;
       
  1338 }
       
  1339 
       
  1340 bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node)
       
  1341 {
       
  1342     DEBUG_THIS_RULE();
       
  1343 
       
  1344     PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
       
  1345     while (parsePtrOperator(*ptr_operators_tail))
       
  1346         ptr_operators_tail = &(*ptr_operators_tail)->next;
       
  1347 
       
  1348     unsigned after_ptr_operators = cursor();
       
  1349 
       
  1350     if (LA() == T_LPAREN) {
       
  1351         unsigned lparen_token = consumeToken();
       
  1352         DeclaratorAST *declarator = 0;
       
  1353         if (parseAbstractDeclarator(declarator) && LA() == T_RPAREN) {
       
  1354             NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
       
  1355             nested_declarator->lparen_token = lparen_token;
       
  1356             nested_declarator->declarator = declarator;
       
  1357             nested_declarator->rparen_token = consumeToken();
       
  1358             DeclaratorAST *ast = new (_pool) DeclaratorAST;
       
  1359             ast->ptr_operator_list = ptr_operators;
       
  1360             ast->core_declarator = nested_declarator;
       
  1361             node = ast;
       
  1362             return true;
       
  1363         }
       
  1364     }
       
  1365 
       
  1366     rewind(after_ptr_operators);
       
  1367     if (ptr_operators) {
       
  1368         DeclaratorAST *ast = new (_pool) DeclaratorAST;
       
  1369         ast->ptr_operator_list = ptr_operators;
       
  1370         node = ast;
       
  1371     }
       
  1372 
       
  1373     return true;
       
  1374 }
       
  1375 
       
  1376 bool Parser::parseAbstractDeclarator(DeclaratorAST *&node)
       
  1377 {
       
  1378     DEBUG_THIS_RULE();
       
  1379     if (! parseAbstractCoreDeclarator(node))
       
  1380         return false;
       
  1381 
       
  1382     PostfixDeclaratorListAST *postfix_declarators = 0,
       
  1383         **postfix_ptr = &postfix_declarators;
       
  1384 
       
  1385     for (;;) {
       
  1386         if (LA() == T_LPAREN) {
       
  1387             FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
       
  1388             ast->lparen_token = consumeToken();
       
  1389             if (LA() == T_RPAREN || parseParameterDeclarationClause(ast->parameters)) {
       
  1390                 if (LA() == T_RPAREN)
       
  1391                     ast->rparen_token = consumeToken();
       
  1392             }
       
  1393             parseCvQualifiers(ast->cv_qualifier_list);
       
  1394             parseExceptionSpecification(ast->exception_specification);
       
  1395             *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
       
  1396             postfix_ptr = &(*postfix_ptr)->next;
       
  1397         } else if (LA() == T_LBRACKET) {
       
  1398             ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST;
       
  1399             ast->lbracket_token = consumeToken();
       
  1400             if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) {
       
  1401                 if (LA() == T_RBRACKET)
       
  1402                     ast->rbracket_token = consumeToken();
       
  1403             }
       
  1404             *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
       
  1405             postfix_ptr = &(*postfix_ptr)->next;
       
  1406         } else
       
  1407             break;
       
  1408     }
       
  1409 
       
  1410     if (postfix_declarators) {
       
  1411         if (! node)
       
  1412             node = new (_pool) DeclaratorAST;
       
  1413 
       
  1414         node->postfix_declarator_list = postfix_declarators;
       
  1415     }
       
  1416 
       
  1417     return true;
       
  1418 }
       
  1419 
       
  1420 bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
       
  1421 {
       
  1422     DEBUG_THIS_RULE();
       
  1423     if (LA() == T_ENUM) {
       
  1424         unsigned enum_token = consumeToken();
       
  1425         NameAST *name = 0;
       
  1426         parseName(name);
       
  1427         if (LA() == T_LBRACE) {
       
  1428             EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
       
  1429             ast->enum_token = enum_token;
       
  1430             ast->name = name;
       
  1431             ast->lbrace_token = consumeToken();
       
  1432             unsigned comma_token = 0;
       
  1433             EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
       
  1434             while (int tk = LA()) {
       
  1435                 if (tk == T_RBRACE)
       
  1436                     break;
       
  1437 
       
  1438                 if (LA() != T_IDENTIFIER) {
       
  1439                     _translationUnit->error(cursor(), "expected identifier before '%s'", tok().spell());
       
  1440                     skipUntil(T_IDENTIFIER);
       
  1441                 }
       
  1442 
       
  1443                 if (parseEnumerator(*enumerator_ptr)) {
       
  1444                     enumerator_ptr = &(*enumerator_ptr)->next;
       
  1445                 }
       
  1446 
       
  1447                 if (LA() != T_RBRACE)
       
  1448                     match(T_COMMA, &comma_token);
       
  1449             }
       
  1450             match(T_RBRACE, &ast->rbrace_token);
       
  1451             node = new (_pool) SpecifierListAST(ast);
       
  1452             return true;
       
  1453         }
       
  1454     }
       
  1455     return false;
       
  1456 }
       
  1457 
       
  1458 bool Parser::parseTemplateParameterList(DeclarationListAST *&node)
       
  1459 {
       
  1460     DEBUG_THIS_RULE();
       
  1461     DeclarationListAST **template_parameter_ptr = &node;
       
  1462     DeclarationAST *declaration = 0;
       
  1463     if (parseTemplateParameter(declaration)) {
       
  1464         *template_parameter_ptr = new (_pool) DeclarationListAST;
       
  1465         (*template_parameter_ptr)->value = declaration;
       
  1466         template_parameter_ptr = &(*template_parameter_ptr)->next;
       
  1467 
       
  1468         while (LA() == T_COMMA) {
       
  1469             consumeToken(); // XXX Store this token somewhere
       
  1470 
       
  1471             declaration = 0;
       
  1472             if (parseTemplateParameter(declaration)) {
       
  1473                 *template_parameter_ptr = new (_pool) DeclarationListAST;
       
  1474                 (*template_parameter_ptr)->value = declaration;
       
  1475                 template_parameter_ptr = &(*template_parameter_ptr)->next;
       
  1476             }
       
  1477         }
       
  1478         return true;
       
  1479     }
       
  1480     return false;
       
  1481 }
       
  1482 
       
  1483 bool Parser::parseTemplateParameter(DeclarationAST *&node)
       
  1484 {
       
  1485     DEBUG_THIS_RULE();
       
  1486     if (parseTypeParameter(node))
       
  1487         return true;
       
  1488     bool previousTemplateArguments = switchTemplateArguments(true);
       
  1489     bool parsed = parseParameterDeclaration(node);
       
  1490     (void) switchTemplateArguments(previousTemplateArguments);
       
  1491     return parsed;
       
  1492 }
       
  1493 
       
  1494 bool Parser::parseTypenameTypeParameter(DeclarationAST *&node)
       
  1495 {
       
  1496     DEBUG_THIS_RULE();
       
  1497     if (LA() == T_CLASS || LA() == T_TYPENAME) {
       
  1498         TypenameTypeParameterAST *ast = new (_pool) TypenameTypeParameterAST;
       
  1499         ast->classkey_token = consumeToken();
       
  1500         parseName(ast->name);
       
  1501         if (LA() == T_EQUAL) {
       
  1502             ast->equal_token = consumeToken();
       
  1503             parseTypeId(ast->type_id);
       
  1504         }
       
  1505         node = ast;
       
  1506         return true;
       
  1507     }
       
  1508     return false;
       
  1509 }
       
  1510 
       
  1511 bool Parser::parseTemplateTypeParameter(DeclarationAST *&node)
       
  1512 {
       
  1513     DEBUG_THIS_RULE();
       
  1514     if (LA() == T_TEMPLATE) {
       
  1515         TemplateTypeParameterAST *ast = new (_pool) TemplateTypeParameterAST;
       
  1516         ast->template_token = consumeToken();
       
  1517         if (LA() == T_LESS)
       
  1518             ast->less_token = consumeToken();
       
  1519         parseTemplateParameterList(ast->template_parameter_list);
       
  1520         if (LA() == T_GREATER)
       
  1521             ast->greater_token = consumeToken();
       
  1522         if (LA() == T_CLASS)
       
  1523             ast->class_token = consumeToken();
       
  1524 
       
  1525         // parse optional name
       
  1526         parseName(ast->name);
       
  1527 
       
  1528         if (LA() == T_EQUAL) {
       
  1529             ast->equal_token = consumeToken();
       
  1530             parseTypeId(ast->type_id);
       
  1531         }
       
  1532         node = ast;
       
  1533         return true;
       
  1534     }
       
  1535     return false;
       
  1536 }
       
  1537 
       
  1538 bool Parser::parseTypeParameter(DeclarationAST *&node)
       
  1539 {
       
  1540     DEBUG_THIS_RULE();
       
  1541     if (LA() == T_CLASS || LA() == T_TYPENAME)
       
  1542         return parseTypenameTypeParameter(node);
       
  1543     else if (LA() == T_TEMPLATE)
       
  1544         return parseTemplateTypeParameter(node);
       
  1545     else
       
  1546         return false;
       
  1547 }
       
  1548 
       
  1549 bool Parser::parseTypeId(ExpressionAST *&node)
       
  1550 {
       
  1551     DEBUG_THIS_RULE();
       
  1552     SpecifierListAST *type_specifier = 0;
       
  1553     if (parseTypeSpecifier(type_specifier)) {
       
  1554         TypeIdAST *ast = new (_pool) TypeIdAST;
       
  1555         ast->type_specifier_list = type_specifier;
       
  1556         parseAbstractDeclarator(ast->declarator);
       
  1557         node = ast;
       
  1558         return true;
       
  1559     }
       
  1560     return false;
       
  1561 }
       
  1562 
       
  1563 bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node)
       
  1564 {
       
  1565     DEBUG_THIS_RULE();
       
  1566     if (LA() == T_RPAREN)
       
  1567         return true; // nothing to do
       
  1568 
       
  1569     DeclarationListAST *parameter_declarations = 0;
       
  1570 
       
  1571     unsigned dot_dot_dot_token = 0;
       
  1572     if (LA() == T_DOT_DOT_DOT)
       
  1573         dot_dot_dot_token = consumeToken();
       
  1574     else {
       
  1575         parseParameterDeclarationList(parameter_declarations);
       
  1576 
       
  1577         if (LA() == T_DOT_DOT_DOT) {
       
  1578             dot_dot_dot_token = consumeToken();
       
  1579         } else if (LA() == T_COMMA && LA(2) == T_DOT_DOT_DOT) {
       
  1580             consumeToken(); // skip comma
       
  1581             dot_dot_dot_token = consumeToken();
       
  1582         }
       
  1583     }
       
  1584 
       
  1585     if (parameter_declarations || dot_dot_dot_token) {
       
  1586         ParameterDeclarationClauseAST *ast = new (_pool) ParameterDeclarationClauseAST;
       
  1587         ast->parameter_declaration_list = parameter_declarations;
       
  1588         ast->dot_dot_dot_token = dot_dot_dot_token;
       
  1589         node = ast;
       
  1590     }
       
  1591 
       
  1592     return true;
       
  1593 }
       
  1594 
       
  1595 bool Parser::parseParameterDeclarationList(DeclarationListAST *&node)
       
  1596 {
       
  1597     DEBUG_THIS_RULE();
       
  1598     if (LA() == T_DOT_DOT_DOT || (LA() == T_COMMA && LA(2) == T_DOT_DOT_DOT))
       
  1599         return false; // nothing to do.
       
  1600 
       
  1601     DeclarationListAST **parameter_declaration_ptr = &node;
       
  1602     DeclarationAST *declaration = 0;
       
  1603     if (parseParameterDeclaration(declaration)) {
       
  1604         *parameter_declaration_ptr = new (_pool) DeclarationListAST;
       
  1605         (*parameter_declaration_ptr)->value = declaration;
       
  1606         parameter_declaration_ptr = &(*parameter_declaration_ptr)->next;
       
  1607         while (LA() == T_COMMA) {
       
  1608             consumeToken();
       
  1609 
       
  1610             if (LA() == T_DOT_DOT_DOT)
       
  1611                 break;
       
  1612 
       
  1613             declaration = 0;
       
  1614             if (parseParameterDeclaration(declaration)) {
       
  1615                 *parameter_declaration_ptr = new (_pool) DeclarationListAST;
       
  1616                 (*parameter_declaration_ptr)->value = declaration;
       
  1617                 parameter_declaration_ptr = &(*parameter_declaration_ptr)->next;
       
  1618             }
       
  1619         }
       
  1620         return true;
       
  1621     }
       
  1622     return false;
       
  1623 }
       
  1624 
       
  1625 bool Parser::parseParameterDeclaration(DeclarationAST *&node)
       
  1626 {
       
  1627     DEBUG_THIS_RULE();
       
  1628     SpecifierListAST *decl_specifier_seq = 0;
       
  1629     if (parseDeclSpecifierSeq(decl_specifier_seq)) {
       
  1630         ParameterDeclarationAST *ast = new (_pool) ParameterDeclarationAST;
       
  1631         ast->type_specifier_list = decl_specifier_seq;
       
  1632         parseDeclaratorOrAbstractDeclarator(ast->declarator);
       
  1633         if (LA() == T_EQUAL) {
       
  1634             ast->equal_token = consumeToken();
       
  1635             parseLogicalOrExpression(ast->expression);
       
  1636         }
       
  1637 
       
  1638         node = ast;
       
  1639         return true;
       
  1640     }
       
  1641     return false;
       
  1642 }
       
  1643 
       
  1644 bool Parser::parseClassSpecifier(SpecifierListAST *&node)
       
  1645 {
       
  1646     DEBUG_THIS_RULE();
       
  1647     if (! lookAtClassKey())
       
  1648         return false;
       
  1649 
       
  1650     unsigned classkey_token = consumeToken();
       
  1651 
       
  1652     SpecifierListAST *attributes = 0, **attr_ptr = &attributes;
       
  1653     while (LA() == T___ATTRIBUTE__) {
       
  1654         parseAttributeSpecifier(*attr_ptr);
       
  1655         attr_ptr = &(*attr_ptr)->next;
       
  1656     }
       
  1657 
       
  1658     if (LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER) {
       
  1659         _translationUnit->warning(cursor(), "skip identifier `%s'",
       
  1660                                   tok().spell());
       
  1661         consumeToken();
       
  1662     }
       
  1663 
       
  1664     NameAST *name = 0;
       
  1665     parseName(name);
       
  1666 
       
  1667     bool parsed = false;
       
  1668 
       
  1669     const bool previousInFunctionBody = _inFunctionBody;
       
  1670     _inFunctionBody = false;
       
  1671 
       
  1672     unsigned colon_token = 0;
       
  1673 
       
  1674     if (LA() == T_COLON || LA() == T_LBRACE) {
       
  1675         BaseSpecifierListAST *base_clause_list = 0;
       
  1676 
       
  1677         if (LA() == T_COLON) {
       
  1678             colon_token = cursor();
       
  1679 
       
  1680             parseBaseClause(base_clause_list);
       
  1681 
       
  1682             if (LA() != T_LBRACE) {
       
  1683                 _translationUnit->error(cursor(), "expected `{' before `%s'", tok().spell());
       
  1684 
       
  1685                 const unsigned saved = cursor();
       
  1686 
       
  1687                 for (int n = 0; n < 3 && LA() != T_EOF_SYMBOL; ++n, consumeToken()) {
       
  1688                     if (LA() == T_LBRACE)
       
  1689                         break;
       
  1690                 }
       
  1691 
       
  1692                 if (LA() != T_LBRACE)
       
  1693                     rewind(saved);
       
  1694             }
       
  1695         }
       
  1696 
       
  1697         ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST;
       
  1698         ast->classkey_token = classkey_token;
       
  1699         ast->attribute_list = attributes;
       
  1700         ast->name = name;
       
  1701         ast->colon_token = colon_token;
       
  1702         ast->base_clause_list = base_clause_list;
       
  1703 
       
  1704         if (LA() == T_LBRACE)
       
  1705             ast->lbrace_token = consumeToken();
       
  1706 
       
  1707         DeclarationListAST **declaration_ptr = &ast->member_specifier_list;
       
  1708         while (int tk = LA()) {
       
  1709             if (tk == T_RBRACE) {
       
  1710                 ast->rbrace_token = consumeToken();
       
  1711                 break;
       
  1712             }
       
  1713 
       
  1714             unsigned start_declaration = cursor();
       
  1715             DeclarationAST *declaration = 0;
       
  1716             if (parseMemberSpecification(declaration)) {
       
  1717                 if (declaration) {  // paranoia check
       
  1718                     *declaration_ptr = new (_pool) DeclarationListAST;
       
  1719                     (*declaration_ptr)->value = declaration;
       
  1720                     declaration_ptr = &(*declaration_ptr)->next;
       
  1721                 }
       
  1722 
       
  1723                 if (cursor() == start_declaration) { // more paranoia
       
  1724                     rewind(start_declaration + 1);
       
  1725                     skipUntilDeclaration();
       
  1726                 }
       
  1727             } else {
       
  1728                 _translationUnit->error(start_declaration, "expected a declaration");
       
  1729                 rewind(start_declaration + 1);
       
  1730                 skipUntilDeclaration();
       
  1731             }
       
  1732         }
       
  1733         node = new (_pool) SpecifierListAST(ast);
       
  1734         parsed = true;
       
  1735     }
       
  1736 
       
  1737     _inFunctionBody = previousInFunctionBody;
       
  1738 
       
  1739     return parsed;
       
  1740 }
       
  1741 
       
  1742 bool Parser::parseAccessSpecifier(SpecifierAST *&node)
       
  1743 {
       
  1744     DEBUG_THIS_RULE();
       
  1745     switch (LA()) {
       
  1746     case T_PUBLIC:
       
  1747     case T_PROTECTED:
       
  1748     case T_PRIVATE: {
       
  1749         SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST;
       
  1750         ast->specifier_token = consumeToken();
       
  1751         node = ast;
       
  1752         return true;
       
  1753     }
       
  1754 
       
  1755     default:
       
  1756         return false;
       
  1757     } // switch
       
  1758 }
       
  1759 
       
  1760 bool Parser::parseAccessDeclaration(DeclarationAST *&node)
       
  1761 {
       
  1762     DEBUG_THIS_RULE();
       
  1763     if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_Q_SIGNALS || LA() == T_Q_SLOTS) {
       
  1764         bool isSignals = LA() == T_Q_SIGNALS;
       
  1765         bool isSlots = LA() == T_Q_SLOTS;
       
  1766         AccessDeclarationAST *ast = new (_pool) AccessDeclarationAST;
       
  1767         ast->access_specifier_token = consumeToken();
       
  1768         if (! isSignals && (LA() == T_Q_SLOTS || isSlots))
       
  1769             ast->slots_token = consumeToken();
       
  1770         match(T_COLON, &ast->colon_token);
       
  1771         node = ast;
       
  1772         return true;
       
  1773     }
       
  1774     return false;
       
  1775 }
       
  1776 
       
  1777 #ifdef ICHECK_BUILD
       
  1778 bool Parser::parseQPropertyDeclaration(DeclarationAST *&node)
       
  1779 {
       
  1780     /*
       
  1781      Q_PROPERTY(type name
       
  1782             READ getFunction
       
  1783             [WRITE setFunction]
       
  1784             [RESET resetFunction]
       
  1785             [NOTIFY notifySignal]
       
  1786             [DESIGNABLE bool]
       
  1787             [SCRIPTABLE bool]
       
  1788             [STORED bool]
       
  1789             [USER bool]
       
  1790             [CONSTANT]
       
  1791             [FINAL])*/
       
  1792     DEBUG_THIS_RULE();
       
  1793     if (LA() == T_Q_PROPERTY) {
       
  1794         QPropertyDeclarationAST *ast = new (_pool)QPropertyDeclarationAST;
       
  1795         ast->property_specifier_token = consumeToken();
       
  1796         if(LA() == T_LPAREN){
       
  1797             ast->lparen_token = consumeToken();
       
  1798             QString tokenstr;
       
  1799             tokenstr = tok().spell();
       
  1800             //read the type and the name of the type
       
  1801             if(tokenstr !=  "READ" ){
       
  1802                 ast->type_token = consumeToken();
       
  1803                 tokenstr = tok().spell();
       
  1804             }
       
  1805             if(tokenstr !=  "READ" ){
       
  1806                 ast->type_name_token = consumeToken();
       
  1807                 tokenstr = tok().spell();
       
  1808             }
       
  1809             unsigned fctdefinition = 0;
       
  1810             unsigned fctname = 0;
       
  1811             for(int i = 0; i < 18; i++){
       
  1812                 if(cursor() < _translationUnit->tokenCount() - 1){
       
  1813                     if(LA() == T_RPAREN){
       
  1814                         ast->rparen_token = consumeToken();
       
  1815                         break;
       
  1816                     }
       
  1817                     tokenstr = tok().spell();
       
  1818                     fctdefinition = consumeToken();
       
  1819                     fctname = consumeToken();
       
  1820                     if(tokenstr == "READ"){
       
  1821                         ast->read_token = fctdefinition;
       
  1822                         ast->read_function_token = fctname;
       
  1823                     }
       
  1824                     else if(tokenstr == "WRITE"){
       
  1825                         ast->write_token = fctdefinition;
       
  1826                         ast->write_function_token = fctname;
       
  1827                     }
       
  1828                     else if(tokenstr == "RESET"){
       
  1829                         ast->reset_token = fctdefinition;
       
  1830                         ast->reset_function_token = fctname;
       
  1831                     }
       
  1832                     else if(tokenstr == "NOTIFY"){
       
  1833                         ast->notify_token = fctdefinition;
       
  1834                         ast->notify_function_token = fctname;
       
  1835                     }
       
  1836                 }
       
  1837             }
       
  1838         }
       
  1839         node = ast;
       
  1840         return true;
       
  1841     }
       
  1842     return false;
       
  1843 }
       
  1844 
       
  1845 bool Parser::parseQEnumDeclaration(DeclarationAST *&node)
       
  1846 {
       
  1847      /*Q_ENUMS(ConnectionState)*/
       
  1848     DEBUG_THIS_RULE();
       
  1849     if (LA() == T_Q_ENUMS) {
       
  1850         QEnumDeclarationAST *ast = new (_pool)QEnumDeclarationAST;
       
  1851         ast->enum_specifier_token = consumeToken();
       
  1852         EnumeratorListAST** enumerator_list_ptr;
       
  1853         enumerator_list_ptr = &ast->enumerator_list;
       
  1854 
       
  1855         if(LA() == T_LPAREN){
       
  1856             ast->lparen_token = consumeToken();
       
  1857             while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){
       
  1858                 *enumerator_list_ptr = new (_pool) EnumeratorListAST;
       
  1859                 EnumeratorAST *pdecl = new (_pool) EnumeratorAST;
       
  1860                 pdecl->identifier_token = consumeToken();
       
  1861                 (*enumerator_list_ptr)->value = pdecl;
       
  1862                 enumerator_list_ptr = &(*enumerator_list_ptr)->next;
       
  1863                 if (LA() == T_COMMA)
       
  1864                     consumeToken();
       
  1865             }
       
  1866             if(LA() == T_RPAREN)
       
  1867                 ast->rparen_token = consumeToken();
       
  1868         }
       
  1869         node = ast;
       
  1870         return true;
       
  1871     }
       
  1872     return false;
       
  1873 }
       
  1874 
       
  1875 bool Parser::parseQFlags(DeclarationAST *&node)
       
  1876 {
       
  1877      /*Q_FLAGS(enum1 enum2 flags1)*/
       
  1878     DEBUG_THIS_RULE();
       
  1879     if (LA() == T_Q_FLAGS) {
       
  1880         QFlagsDeclarationAST *ast = new (_pool)QFlagsDeclarationAST;
       
  1881         ast->flags_specifier_token = consumeToken();
       
  1882         EnumeratorListAST** enumerator_list_ptr;
       
  1883         enumerator_list_ptr = &ast->enumerator_list;
       
  1884         if(LA() == T_LPAREN){
       
  1885             ast->lparen_token = consumeToken();
       
  1886             while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){
       
  1887                 *enumerator_list_ptr = new (_pool) EnumeratorListAST;
       
  1888                 EnumeratorAST *pdecl = new (_pool) EnumeratorAST;
       
  1889                 pdecl->identifier_token = consumeToken();
       
  1890                 (*enumerator_list_ptr)->value = pdecl;
       
  1891                 enumerator_list_ptr = &(*enumerator_list_ptr)->next;
       
  1892                 if (LA() == T_COMMA)
       
  1893                     consumeToken();
       
  1894             }
       
  1895             if(LA() == T_RPAREN)
       
  1896                 ast->rparen_token = consumeToken();
       
  1897         }
       
  1898         node = ast;
       
  1899         return true;
       
  1900     }
       
  1901     return false;
       
  1902 }
       
  1903 
       
  1904 bool Parser::parseQDeclareFlags(DeclarationAST *&node)
       
  1905 {
       
  1906      /*Q_DECLARE_FLAGS(flag enum)*/
       
  1907     DEBUG_THIS_RULE();
       
  1908     if (LA() == T_Q_DECLARE_FLAGS) {
       
  1909         QDeclareFlagsDeclarationAST *ast = new (_pool)QDeclareFlagsDeclarationAST;
       
  1910         ast->declareflags_specifier_token = consumeToken();
       
  1911         if(LA() == T_LPAREN){
       
  1912             ast->lparen_token = consumeToken();
       
  1913             if(LA() != T_EOF_SYMBOL)
       
  1914                 ast->flag_token = consumeToken();
       
  1915             if(LA() == T_COMMA && LA() != T_EOF_SYMBOL)
       
  1916                 consumeToken();
       
  1917             if(LA() != T_EOF_SYMBOL)
       
  1918                 ast->enum_token = consumeToken();
       
  1919             if(LA() != T_EOF_SYMBOL && LA() == T_RPAREN)
       
  1920                 ast->rparen_token = consumeToken();
       
  1921         }
       
  1922         node = ast;
       
  1923         return true;
       
  1924     }
       
  1925     return false;
       
  1926 }
       
  1927 #endif
       
  1928 
       
  1929 bool Parser::parseMemberSpecification(DeclarationAST *&node)
       
  1930 {
       
  1931     DEBUG_THIS_RULE();
       
  1932     switch (LA()) {
       
  1933     case T_SEMICOLON:
       
  1934         return parseEmptyDeclaration(node);
       
  1935 
       
  1936     case T_USING:
       
  1937         return parseUsing(node);
       
  1938 
       
  1939     case T_TEMPLATE:
       
  1940         return parseTemplateDeclaration(node);
       
  1941 
       
  1942     case T_Q_SIGNALS:
       
  1943     case T_PUBLIC:
       
  1944     case T_PROTECTED:
       
  1945     case T_PRIVATE:
       
  1946     case T_Q_SLOTS:
       
  1947         return parseAccessDeclaration(node);
       
  1948 
       
  1949 #ifdef ICHECK_BUILD
       
  1950     case T_Q_PROPERTY:
       
  1951         return parseQPropertyDeclaration(node);
       
  1952 
       
  1953     case T_Q_ENUMS:
       
  1954         return parseQEnumDeclaration(node);
       
  1955 
       
  1956     case T_Q_FLAGS:
       
  1957         return parseQFlags(node);
       
  1958 
       
  1959     case T_Q_DECLARE_FLAGS:
       
  1960         return parseQDeclareFlags(node);
       
  1961 #endif
       
  1962 
       
  1963     default:
       
  1964         return parseSimpleDeclaration(node, /*acceptStructDeclarator=*/true);
       
  1965     } // switch
       
  1966 }
       
  1967 
       
  1968 bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
       
  1969 {
       
  1970     DEBUG_THIS_RULE();
       
  1971     if (LA() == T_COLON) {
       
  1972         unsigned colon_token = consumeToken();
       
  1973 
       
  1974         CtorInitializerAST *ast = new (_pool) CtorInitializerAST;
       
  1975         ast->colon_token = colon_token;
       
  1976 
       
  1977         parseMemInitializerList(ast->member_initializer_list);
       
  1978         node = ast;
       
  1979         return true;
       
  1980     }
       
  1981     return false;
       
  1982 }
       
  1983 
       
  1984 bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node)
       
  1985 {
       
  1986     DEBUG_THIS_RULE();
       
  1987     if (lookAtClassKey() || LA() == T_ENUM || LA() == T_TYPENAME) {
       
  1988         unsigned classkey_token = consumeToken();
       
  1989         NameAST *name = 0;
       
  1990         if (parseName(name)) {
       
  1991             ElaboratedTypeSpecifierAST *ast = new (_pool) ElaboratedTypeSpecifierAST;
       
  1992             ast->classkey_token = classkey_token;
       
  1993             ast->name = name;
       
  1994             node = new (_pool) SpecifierListAST(ast);
       
  1995             return true;
       
  1996         }
       
  1997     }
       
  1998     return false;
       
  1999 }
       
  2000 
       
  2001 bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
       
  2002 {
       
  2003     DEBUG_THIS_RULE();
       
  2004     if (LA() == T_THROW) {
       
  2005         ExceptionSpecificationAST *ast = new (_pool) ExceptionSpecificationAST;
       
  2006         ast->throw_token = consumeToken();
       
  2007         if (LA() == T_LPAREN)
       
  2008             ast->lparen_token = consumeToken();
       
  2009         if (LA() == T_DOT_DOT_DOT)
       
  2010             ast->dot_dot_dot_token = consumeToken();
       
  2011         else
       
  2012             parseTypeIdList(ast->type_id_list);
       
  2013         if (LA() == T_RPAREN)
       
  2014             ast->rparen_token = consumeToken();
       
  2015         node = ast;
       
  2016         return true;
       
  2017     }
       
  2018     return false;
       
  2019 }
       
  2020 
       
  2021 bool Parser::parseEnumerator(EnumeratorListAST *&node)
       
  2022 {
       
  2023     DEBUG_THIS_RULE();
       
  2024     if (LA() == T_IDENTIFIER) {
       
  2025         EnumeratorAST *ast = new (_pool) EnumeratorAST;
       
  2026         ast->identifier_token = consumeToken();
       
  2027 
       
  2028         if (LA() == T_EQUAL) {
       
  2029             ast->equal_token = consumeToken();
       
  2030             parseConstantExpression(ast->expression);
       
  2031         }
       
  2032 
       
  2033         node = new (_pool) EnumeratorListAST;
       
  2034         node->value = ast;
       
  2035         return true;
       
  2036     }
       
  2037     return false;
       
  2038 }
       
  2039 
       
  2040 bool Parser::parseInitDeclarator(DeclaratorAST *&node,
       
  2041         bool acceptStructDeclarator)
       
  2042 {
       
  2043     DEBUG_THIS_RULE();
       
  2044     unsigned start = cursor();
       
  2045 
       
  2046     if (acceptStructDeclarator && LA() == T_COLON) {
       
  2047         // anonymous bit-field declaration.
       
  2048         // ### TODO create the AST
       
  2049     } else if (! parseDeclarator(node, /*stopAtCppInitializer = */ ! acceptStructDeclarator)) {
       
  2050         return false;
       
  2051     }
       
  2052 
       
  2053     if (LA() == T_ASM && LA(2) == T_LPAREN) { // ### FIXME
       
  2054         consumeToken();
       
  2055 
       
  2056         if (skip(T_LPAREN, T_RPAREN))
       
  2057             consumeToken();
       
  2058     }
       
  2059 
       
  2060     if (acceptStructDeclarator && node &&
       
  2061             ! node->postfix_declarator_list &&
       
  2062             node->core_declarator &&
       
  2063             node->core_declarator->asNestedDeclarator()) {
       
  2064         rewind(start);
       
  2065         return false;
       
  2066     }
       
  2067 
       
  2068     if (acceptStructDeclarator && LA() == T_COLON
       
  2069             && (! node || ! node->postfix_declarator_list)) {
       
  2070         unsigned colon_token = consumeToken();
       
  2071         ExpressionAST *expression = 0;
       
  2072         if (parseConstantExpression(expression) && (LA() == T_COMMA ||
       
  2073                                                     LA() == T_SEMICOLON)) {
       
  2074             // recognized a bitfielddeclarator.
       
  2075             // ### TODO create the AST
       
  2076             return true;
       
  2077         }
       
  2078         rewind(colon_token);
       
  2079     } else if (LA() == T_EQUAL || (! acceptStructDeclarator && LA() == T_LPAREN)) {
       
  2080         parseInitializer(node->initializer, &node->equals_token);
       
  2081     }
       
  2082     return true;
       
  2083 }
       
  2084 
       
  2085 bool Parser::parseBaseClause(BaseSpecifierListAST *&node)
       
  2086 {
       
  2087     DEBUG_THIS_RULE();
       
  2088 
       
  2089     if (LA() == T_COLON) {
       
  2090         consumeToken(); // ### remove me
       
  2091 
       
  2092         BaseSpecifierListAST **ast = &node;
       
  2093         if (parseBaseSpecifier(*ast)) {
       
  2094             ast = &(*ast)->next;
       
  2095 
       
  2096             while (LA() == T_COMMA) {
       
  2097                 consumeToken(); // consume T_COMMA
       
  2098 
       
  2099                 if (parseBaseSpecifier(*ast))
       
  2100                     ast = &(*ast)->next;
       
  2101             }
       
  2102         }
       
  2103 
       
  2104         return true;
       
  2105     }
       
  2106     return false;
       
  2107 }
       
  2108 
       
  2109 bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token)
       
  2110 {
       
  2111     DEBUG_THIS_RULE();
       
  2112     if (LA() == T_LPAREN) {
       
  2113         return parsePrimaryExpression(node);
       
  2114     } else if (LA() == T_EQUAL) {
       
  2115         (*equals_token) = consumeToken();
       
  2116         return parseInitializerClause(node);
       
  2117     }
       
  2118     return false;
       
  2119 }
       
  2120 
       
  2121 bool Parser::parseMemInitializerList(MemInitializerListAST *&node)
       
  2122 {
       
  2123     DEBUG_THIS_RULE();
       
  2124     MemInitializerListAST **initializer = &node;
       
  2125 
       
  2126     if (parseMemInitializer(*initializer)) {
       
  2127         initializer = &(*initializer)->next;
       
  2128 
       
  2129         while (true) {
       
  2130 
       
  2131             if (LA() == T_LBRACE)
       
  2132                 break;
       
  2133 
       
  2134             else if (LA() == T_COMMA || (LA() == T_IDENTIFIER && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON))) {
       
  2135                 if (LA() != T_COMMA)
       
  2136                     _translationUnit->error(cursor(), "expected `,'");
       
  2137                 else
       
  2138                     consumeToken();
       
  2139 
       
  2140                 if (parseMemInitializer(*initializer))
       
  2141                     initializer = &(*initializer)->next;
       
  2142                 else
       
  2143                     _translationUnit->error(cursor(), "expected a member initializer");
       
  2144 
       
  2145             } else break;
       
  2146         }
       
  2147 
       
  2148         if (LA() != T_LBRACE)
       
  2149             _translationUnit->error(cursor(), "expected `{'");
       
  2150 
       
  2151         return true;
       
  2152     }
       
  2153 
       
  2154     return false;
       
  2155 }
       
  2156 
       
  2157 bool Parser::parseMemInitializer(MemInitializerListAST *&node)
       
  2158 {
       
  2159     DEBUG_THIS_RULE();
       
  2160     NameAST *name = 0;
       
  2161     if (! parseName(name))
       
  2162         return false;
       
  2163 
       
  2164     MemInitializerAST *ast = new (_pool) MemInitializerAST;
       
  2165     ast->name = name;
       
  2166     match(T_LPAREN, &ast->lparen_token);
       
  2167     parseExpressionList(ast->expression_list);
       
  2168     match(T_RPAREN, &ast->rparen_token);
       
  2169 
       
  2170     node = new (_pool) MemInitializerListAST;
       
  2171     node->value = ast;
       
  2172     return true;
       
  2173 }
       
  2174 
       
  2175 bool Parser::parseTypeIdList(ExpressionListAST *&node)
       
  2176 {
       
  2177     DEBUG_THIS_RULE();
       
  2178     ExpressionListAST **expression_list_ptr = &node;
       
  2179     ExpressionAST *typeId = 0;
       
  2180     if (parseTypeId(typeId)) {
       
  2181         *expression_list_ptr = new (_pool) ExpressionListAST;
       
  2182         (*expression_list_ptr)->value = typeId;
       
  2183         expression_list_ptr = &(*expression_list_ptr)->next;
       
  2184         while (LA() == T_COMMA) {
       
  2185             consumeToken();
       
  2186 
       
  2187             if (parseTypeId(typeId)) {
       
  2188                 *expression_list_ptr = new (_pool) ExpressionListAST;
       
  2189                 (*expression_list_ptr)->value = typeId;
       
  2190                 expression_list_ptr = &(*expression_list_ptr)->next;
       
  2191             }
       
  2192         }
       
  2193         return true;
       
  2194     }
       
  2195 
       
  2196     return false;
       
  2197 }
       
  2198 
       
  2199 bool Parser::parseExpressionList(ExpressionListAST *&node)
       
  2200 {
       
  2201     DEBUG_THIS_RULE();
       
  2202     ExpressionListAST **expression_list_ptr = &node;
       
  2203     ExpressionAST *expression = 0;
       
  2204     if (parseAssignmentExpression(expression)) {
       
  2205         *expression_list_ptr = new (_pool) ExpressionListAST;
       
  2206         (*expression_list_ptr)->value = expression;
       
  2207         expression_list_ptr = &(*expression_list_ptr)->next;
       
  2208         while (LA() == T_COMMA) {
       
  2209             consumeToken(); // consume T_COMMA
       
  2210 
       
  2211             if (parseAssignmentExpression(expression)) {
       
  2212                 *expression_list_ptr = new (_pool) ExpressionListAST;
       
  2213                 (*expression_list_ptr)->value = expression;
       
  2214                 expression_list_ptr = &(*expression_list_ptr)->next;
       
  2215             }
       
  2216         }
       
  2217         return true;
       
  2218     }
       
  2219     return false;
       
  2220 }
       
  2221 
       
  2222 bool Parser::parseBaseSpecifier(BaseSpecifierListAST *&node)
       
  2223 {
       
  2224     DEBUG_THIS_RULE();
       
  2225     BaseSpecifierAST *ast = new (_pool) BaseSpecifierAST;
       
  2226 
       
  2227     if (LA() == T_VIRTUAL) {
       
  2228         ast->virtual_token = consumeToken();
       
  2229 
       
  2230         int tk = LA();
       
  2231         if (tk == T_PUBLIC || tk == T_PROTECTED || tk == T_PRIVATE)
       
  2232             ast->access_specifier_token = consumeToken();
       
  2233     } else {
       
  2234         int tk = LA();
       
  2235         if (tk == T_PUBLIC || tk == T_PROTECTED || tk == T_PRIVATE)
       
  2236             ast->access_specifier_token = consumeToken();
       
  2237 
       
  2238         if (LA() == T_VIRTUAL)
       
  2239             ast->virtual_token = consumeToken();
       
  2240     }
       
  2241 
       
  2242     parseName(ast->name);
       
  2243     if (! ast->name)
       
  2244         _translationUnit->error(cursor(), "expected class-name");
       
  2245 
       
  2246     node = new (_pool) BaseSpecifierListAST;
       
  2247     node->value = ast;
       
  2248     return true;
       
  2249 }
       
  2250 
       
  2251 bool Parser::parseInitializerList(ExpressionListAST *&node)
       
  2252 {
       
  2253     DEBUG_THIS_RULE();
       
  2254     ExpressionListAST **initializer_ptr = &node;
       
  2255     ExpressionAST *initializer = 0;
       
  2256     if (parseInitializerClause(initializer)) {
       
  2257         *initializer_ptr = new (_pool) ExpressionListAST;
       
  2258         (*initializer_ptr)->value = initializer;
       
  2259         initializer_ptr = &(*initializer_ptr)->next;
       
  2260         while (LA() == T_COMMA) {
       
  2261             consumeToken(); // consume T_COMMA
       
  2262             initializer = 0;
       
  2263             parseInitializerClause(initializer);
       
  2264             *initializer_ptr = new (_pool) ExpressionListAST;
       
  2265             (*initializer_ptr)->value = initializer;
       
  2266             initializer_ptr = &(*initializer_ptr)->next;
       
  2267         }
       
  2268     }
       
  2269     return true;
       
  2270 }
       
  2271 
       
  2272 bool Parser::parseInitializerClause(ExpressionAST *&node)
       
  2273 {
       
  2274     DEBUG_THIS_RULE();
       
  2275     if (LA() == T_LBRACE) {
       
  2276         ArrayInitializerAST *ast = new (_pool) ArrayInitializerAST;
       
  2277         ast->lbrace_token = consumeToken();
       
  2278         parseInitializerList(ast->expression_list);
       
  2279         match(T_RBRACE, &ast->rbrace_token);
       
  2280         node = ast;
       
  2281         return true;
       
  2282     }
       
  2283     return parseAssignmentExpression(node);
       
  2284 }
       
  2285 
       
  2286 bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId)
       
  2287 {
       
  2288     DEBUG_THIS_RULE();
       
  2289     if (LA() == T_TILDE && LA(2) == T_IDENTIFIER) {
       
  2290         DestructorNameAST *ast = new (_pool) DestructorNameAST;
       
  2291         ast->tilde_token = consumeToken();
       
  2292         ast->identifier_token = consumeToken();
       
  2293         node = ast;
       
  2294         return true;
       
  2295     } else if (LA() == T_OPERATOR) {
       
  2296         unsigned operator_token = cursor();
       
  2297         if (parseOperatorFunctionId(node))
       
  2298             return true;
       
  2299         rewind(operator_token);
       
  2300         return parseConversionFunctionId(node);
       
  2301      } else if (LA() == T_IDENTIFIER) {
       
  2302          unsigned identifier_token = cursor();
       
  2303          if (acceptTemplateId && LA(2) == T_LESS && parseTemplateId(node)) {
       
  2304              if (! _templateArguments || (LA() == T_COMMA  || LA() == T_GREATER ||
       
  2305                                           LA() == T_LPAREN || LA() == T_RPAREN  ||
       
  2306                                           LA() == T_COLON_COLON))
       
  2307                  return true;
       
  2308          }
       
  2309          rewind(identifier_token);
       
  2310          SimpleNameAST *ast = new (_pool) SimpleNameAST;
       
  2311          ast->identifier_token = consumeToken();
       
  2312          node = ast;
       
  2313          return true;
       
  2314     } else if (LA() == T_TEMPLATE) {
       
  2315         unsigned template_token = consumeToken();
       
  2316         if (parseTemplateId(node))
       
  2317             return true;
       
  2318         rewind(template_token);
       
  2319     }
       
  2320     return false;
       
  2321 }
       
  2322 
       
  2323 bool Parser::parseStringLiteral(ExpressionAST *&node)
       
  2324 {
       
  2325     DEBUG_THIS_RULE();
       
  2326     if (! (LA() == T_STRING_LITERAL || LA() == T_WIDE_STRING_LITERAL))
       
  2327         return false;
       
  2328 
       
  2329     StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
       
  2330 
       
  2331     while (LA() == T_STRING_LITERAL || LA() == T_WIDE_STRING_LITERAL) {
       
  2332         *ast = new (_pool) StringLiteralAST;
       
  2333         (*ast)->literal_token = consumeToken();
       
  2334         ast = &(*ast)->next;
       
  2335     }
       
  2336     return true;
       
  2337 }
       
  2338 
       
  2339 bool Parser::parseExpressionStatement(StatementAST *&node)
       
  2340 {
       
  2341     DEBUG_THIS_RULE();
       
  2342     if (LA() == T_SEMICOLON) {
       
  2343         ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
       
  2344         match(T_SEMICOLON, &ast->semicolon_token);
       
  2345         node = ast;
       
  2346         return true;
       
  2347     }
       
  2348 
       
  2349     ExpressionAST *expression = 0;
       
  2350     MemoryPool *oldPool = _pool;
       
  2351     MemoryPool tmp;
       
  2352     _pool = &tmp;
       
  2353     if (parseExpression(expression)) {
       
  2354         ExpressionStatementAST *ast = new (oldPool) ExpressionStatementAST;
       
  2355         ast->expression = expression->clone(oldPool);
       
  2356         match(T_SEMICOLON, &ast->semicolon_token);
       
  2357         node = ast;
       
  2358         _pool = oldPool;
       
  2359         return true;
       
  2360     }
       
  2361     _pool = oldPool;
       
  2362 
       
  2363     return false;
       
  2364 }
       
  2365 
       
  2366 bool Parser::parseStatement(StatementAST *&node)
       
  2367 {
       
  2368     DEBUG_THIS_RULE();
       
  2369     switch (LA()) {
       
  2370     case T_WHILE:
       
  2371         return parseWhileStatement(node);
       
  2372 
       
  2373     case T_DO:
       
  2374         return parseDoStatement(node);
       
  2375 
       
  2376     case T_Q_FOREACH:
       
  2377         return parseForeachStatement(node);
       
  2378 
       
  2379     case T_FOR:
       
  2380         return parseForStatement(node);
       
  2381 
       
  2382     case T_IF:
       
  2383         return parseIfStatement(node);
       
  2384 
       
  2385     case T_SWITCH:
       
  2386         return parseSwitchStatement(node);
       
  2387 
       
  2388     case T_TRY:
       
  2389         return parseTryBlockStatement(node);
       
  2390 
       
  2391     case T_CASE:
       
  2392     case T_DEFAULT:
       
  2393         return parseLabeledStatement(node);
       
  2394 
       
  2395     case T_BREAK:
       
  2396         return parseBreakStatement(node);
       
  2397 
       
  2398     case T_CONTINUE:
       
  2399         return parseContinueStatement(node);
       
  2400 
       
  2401     case T_GOTO:
       
  2402         return parseGotoStatement(node);
       
  2403 
       
  2404     case T_RETURN:
       
  2405         return parseReturnStatement(node);
       
  2406 
       
  2407     case T_LBRACE:
       
  2408         return parseCompoundStatement(node);
       
  2409 
       
  2410     case T_ASM:
       
  2411     case T_NAMESPACE:
       
  2412     case T_USING:
       
  2413     case T_TEMPLATE:
       
  2414     case T_CLASS: case T_STRUCT: case T_UNION:
       
  2415         return parseDeclarationStatement(node);
       
  2416 
       
  2417     case T_SEMICOLON: {
       
  2418         ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
       
  2419         ast->semicolon_token = consumeToken();
       
  2420         node = ast;
       
  2421         return true;
       
  2422     }
       
  2423 
       
  2424     case T_AT_SYNCHRONIZED:
       
  2425         return objCEnabled() && parseObjCSynchronizedStatement(node);
       
  2426 
       
  2427     case T_Q_D:
       
  2428     case T_Q_Q: {
       
  2429         QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST;
       
  2430         ast->q_token = consumeToken();
       
  2431         match(T_LPAREN, &ast->lparen_token);
       
  2432         parseTypeId(ast->type_id);
       
  2433         match(T_RPAREN, &ast->rparen_token);
       
  2434         node = ast;
       
  2435     } return true;
       
  2436 
       
  2437     default:
       
  2438         if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
       
  2439             return parseLabeledStatement(node);
       
  2440 
       
  2441         return parseExpressionOrDeclarationStatement(node);
       
  2442     } // switch
       
  2443     return false; //Avoid compiler warning
       
  2444 }
       
  2445 
       
  2446 bool Parser::parseBreakStatement(StatementAST *&node)
       
  2447 {
       
  2448     DEBUG_THIS_RULE();
       
  2449     if (LA() == T_BREAK) {
       
  2450         BreakStatementAST *ast = new (_pool) BreakStatementAST;
       
  2451         ast->break_token = consumeToken();
       
  2452         match(T_SEMICOLON, &ast->semicolon_token);
       
  2453         node = ast;
       
  2454         return true;
       
  2455     }
       
  2456     return false;
       
  2457 }
       
  2458 
       
  2459 bool Parser::parseContinueStatement(StatementAST *&node)
       
  2460 {
       
  2461     DEBUG_THIS_RULE();
       
  2462     if (LA() == T_CONTINUE) {
       
  2463         ContinueStatementAST *ast = new (_pool) ContinueStatementAST;
       
  2464         ast->continue_token = consumeToken();
       
  2465         match(T_SEMICOLON, &ast->semicolon_token);
       
  2466         node = ast;
       
  2467         return true;
       
  2468     }
       
  2469     return false;
       
  2470 }
       
  2471 
       
  2472 bool Parser::parseGotoStatement(StatementAST *&node)
       
  2473 {
       
  2474     DEBUG_THIS_RULE();
       
  2475     if (LA() == T_GOTO) {
       
  2476         GotoStatementAST *ast = new (_pool) GotoStatementAST;
       
  2477         ast->goto_token = consumeToken();
       
  2478         match(T_IDENTIFIER, &ast->identifier_token);
       
  2479         match(T_SEMICOLON, &ast->semicolon_token);
       
  2480         node = ast;
       
  2481         return true;
       
  2482     }
       
  2483     return false;
       
  2484 }
       
  2485 
       
  2486 bool Parser::parseReturnStatement(StatementAST *&node)
       
  2487 {
       
  2488     DEBUG_THIS_RULE();
       
  2489     if (LA() == T_RETURN) {
       
  2490         ReturnStatementAST *ast = new (_pool) ReturnStatementAST;
       
  2491         ast->return_token = consumeToken();
       
  2492         parseExpression(ast->expression);
       
  2493         match(T_SEMICOLON, &ast->semicolon_token);
       
  2494         node = ast;
       
  2495         return true;
       
  2496     }
       
  2497     return false;
       
  2498 }
       
  2499 
       
  2500 bool Parser::isPointerDeclaration(DeclarationStatementAST *ast) const
       
  2501 {
       
  2502     if (! ast)
       
  2503         return false;
       
  2504 
       
  2505     if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) {
       
  2506         if (SpecifierListAST *spec = declaration->decl_specifier_list) {
       
  2507             if (spec->value->asNamedTypeSpecifier() && ! spec->next) {
       
  2508                 if (DeclaratorListAST *declarators = declaration->declarator_list) {
       
  2509                     if (DeclaratorAST *declarator = declarators->value) {
       
  2510                         if (declarator->ptr_operator_list && declarator->equals_token && declarator->initializer) {
       
  2511                             return true;
       
  2512                         }
       
  2513                     }
       
  2514                 }
       
  2515             }
       
  2516         }
       
  2517     }
       
  2518 
       
  2519     return false;
       
  2520 }
       
  2521 
       
  2522 bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast) const
       
  2523 {
       
  2524     if (! ast)
       
  2525         return false;
       
  2526 
       
  2527     if (SimpleDeclarationAST *declaration = ast->declaration->asSimpleDeclaration()) {
       
  2528         if (SpecifierListAST *spec = declaration->decl_specifier_list) {
       
  2529             if (spec->value->asNamedTypeSpecifier() && ! spec->next) {
       
  2530                 if (DeclaratorListAST *declarators = declaration->declarator_list) {
       
  2531                     if (DeclaratorAST *declarator = declarators->value) {
       
  2532                         if (declarator->core_declarator &&
       
  2533                             declarator->core_declarator->asNestedDeclarator()) {
       
  2534                             // recognized name(id-expression)
       
  2535                             return true;
       
  2536                         }
       
  2537                     }
       
  2538                 }
       
  2539             }
       
  2540 
       
  2541         } else if (DeclaratorListAST *declarators = declaration->declarator_list) {
       
  2542             // no decl_specifiers...
       
  2543             if (DeclaratorAST *declarator = declarators->value) {
       
  2544                 if (declarator->postfix_declarator_list && declarator->postfix_declarator_list->value->asFunctionDeclarator()
       
  2545                                                      && ! declarator->initializer) {
       
  2546                     return false;
       
  2547                 }
       
  2548             }
       
  2549 
       
  2550             return true;
       
  2551         }
       
  2552     }
       
  2553 
       
  2554     return false;
       
  2555 }
       
  2556 
       
  2557 bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
       
  2558 {
       
  2559     DEBUG_THIS_RULE();
       
  2560     if (LA() == T_SEMICOLON)
       
  2561         return parseExpressionStatement(node);
       
  2562 
       
  2563     unsigned start = cursor();
       
  2564     bool blocked = blockErrors(true);
       
  2565 
       
  2566     if (parseDeclarationStatement(node)) {
       
  2567         DeclarationStatementAST *stmt = static_cast<DeclarationStatementAST *>(node);
       
  2568 
       
  2569         if (isPointerDeclaration(stmt)) {
       
  2570             blockErrors(blocked);
       
  2571             return true;
       
  2572         }
       
  2573 
       
  2574         if (! maybeAmbiguousStatement(stmt)) {
       
  2575             unsigned end_of_declaration_statement = cursor();
       
  2576             rewind(start);
       
  2577 
       
  2578             StatementAST *expression = 0;
       
  2579             if (parseExpressionStatement(expression) && cursor() == end_of_declaration_statement) {
       
  2580                 // it's an ambiguous expression-or-declaration statement.
       
  2581                 ExpressionOrDeclarationStatementAST *ast = new (_pool) ExpressionOrDeclarationStatementAST;
       
  2582                 ast->declaration = node;
       
  2583                 ast->expression = expression;
       
  2584                 node = ast;
       
  2585             }
       
  2586 
       
  2587             rewind(end_of_declaration_statement);
       
  2588             blockErrors(blocked);
       
  2589             return true;
       
  2590         }
       
  2591     }
       
  2592 
       
  2593     // it's not a declaration statement.
       
  2594     blockErrors(blocked);
       
  2595     rewind(start);
       
  2596     return parseExpressionStatement(node);
       
  2597 }
       
  2598 
       
  2599 bool Parser::parseCondition(ExpressionAST *&node)
       
  2600 {
       
  2601     DEBUG_THIS_RULE();
       
  2602     unsigned start = cursor();
       
  2603 
       
  2604     bool blocked = blockErrors(true);
       
  2605     SpecifierListAST *type_specifier = 0;
       
  2606     if (parseTypeSpecifier(type_specifier)) {
       
  2607         DeclaratorAST *declarator = 0;
       
  2608         if (parseInitDeclarator(declarator, /*acceptStructDeclarator=*/false)) {
       
  2609             if (declarator->initializer) {
       
  2610                 ConditionAST *ast = new (_pool) ConditionAST;
       
  2611                 ast->type_specifier_list = type_specifier;
       
  2612                 ast->declarator = declarator;
       
  2613                 node = ast;
       
  2614                 blockErrors(blocked);
       
  2615                 return true;
       
  2616             }
       
  2617         }
       
  2618     }
       
  2619 
       
  2620     blockErrors(blocked);
       
  2621     rewind(start);
       
  2622     return parseExpression(node);
       
  2623 }
       
  2624 
       
  2625 bool Parser::parseWhileStatement(StatementAST *&node)
       
  2626 {
       
  2627     DEBUG_THIS_RULE();
       
  2628     if (LA() == T_WHILE) {
       
  2629         WhileStatementAST *ast = new (_pool) WhileStatementAST;
       
  2630         ast->while_token = consumeToken();
       
  2631         match(T_LPAREN, &ast->lparen_token);
       
  2632         parseCondition(ast->condition);
       
  2633         match(T_RPAREN, &ast->rparen_token);
       
  2634         parseStatement(ast->statement);
       
  2635         node = ast;
       
  2636         return true;
       
  2637     }
       
  2638     return true;
       
  2639 }
       
  2640 
       
  2641 bool Parser::parseDoStatement(StatementAST *&node)
       
  2642 {
       
  2643     DEBUG_THIS_RULE();
       
  2644     if (LA() == T_DO) {
       
  2645         DoStatementAST *ast = new (_pool) DoStatementAST;
       
  2646         ast->do_token = consumeToken();
       
  2647         parseStatement(ast->statement);
       
  2648         match(T_WHILE, &ast->while_token);
       
  2649         match(T_LPAREN, &ast->lparen_token);
       
  2650         parseExpression(ast->expression);
       
  2651         match(T_RPAREN, &ast->rparen_token);
       
  2652         match(T_SEMICOLON, &ast->semicolon_token);
       
  2653         node = ast;
       
  2654         return true;
       
  2655     }
       
  2656     return false;
       
  2657 }
       
  2658 
       
  2659 bool Parser::parseForeachStatement(StatementAST *&node)
       
  2660 {
       
  2661     DEBUG_THIS_RULE();
       
  2662     if (LA() == T_Q_FOREACH) {
       
  2663         ForeachStatementAST *ast = new (_pool) ForeachStatementAST;
       
  2664         ast->foreach_token = consumeToken();
       
  2665         match(T_LPAREN, &ast->lparen_token);
       
  2666 
       
  2667         unsigned startOfTypeSpecifier = cursor();
       
  2668         bool blocked = blockErrors(true);
       
  2669 
       
  2670         if (parseTypeSpecifier(ast->type_specifier_list))
       
  2671             parseDeclarator(ast->declarator);
       
  2672 
       
  2673         if (! ast->type_specifier_list || ! ast->declarator) {
       
  2674             ast->type_specifier_list = 0;
       
  2675             ast->declarator = 0;
       
  2676 
       
  2677             blockErrors(blocked);
       
  2678             rewind(startOfTypeSpecifier);
       
  2679             parseAssignmentExpression(ast->initializer);
       
  2680         }
       
  2681 
       
  2682         blockErrors(blocked);
       
  2683 
       
  2684         match(T_COMMA, &ast->comma_token);
       
  2685         parseExpression(ast->expression);
       
  2686         match(T_RPAREN, &ast->rparen_token);
       
  2687         parseStatement(ast->statement);
       
  2688 
       
  2689         node = ast;
       
  2690         return true;
       
  2691     }
       
  2692     return false;
       
  2693 }
       
  2694 
       
  2695 bool Parser::parseForStatement(StatementAST *&node)
       
  2696 {
       
  2697     DEBUG_THIS_RULE();
       
  2698     if (LA() != T_FOR)
       
  2699         return false;
       
  2700 
       
  2701     unsigned for_token = consumeToken();
       
  2702     unsigned lparen_token = 0;
       
  2703     match(T_LPAREN, &lparen_token);
       
  2704 
       
  2705     unsigned startOfTypeSpecifier = cursor();
       
  2706     bool blocked = blockErrors(true);
       
  2707 
       
  2708     if (objCEnabled()) {
       
  2709         ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
       
  2710         ast->for_token = for_token;
       
  2711         ast->lparen_token = lparen_token;
       
  2712 
       
  2713         if (parseTypeSpecifier(ast->type_specifier_list))
       
  2714             parseDeclarator(ast->declarator);
       
  2715 
       
  2716         if ((ast->type_specifier_list || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) {
       
  2717             // woops, probably parsed too much: "in" got parsed as a declarator. Let's redo it:
       
  2718             ast->type_specifier_list = 0;
       
  2719             ast->declarator = 0;
       
  2720 
       
  2721             rewind(startOfTypeSpecifier);
       
  2722             parseDeclarator(ast->declarator);
       
  2723         }
       
  2724 
       
  2725         if (! ast->type_specifier_list || ! ast->declarator) {
       
  2726             ast->type_specifier_list = 0;
       
  2727             ast->declarator = 0;
       
  2728 
       
  2729             rewind(startOfTypeSpecifier);
       
  2730             parseAssignmentExpression(ast->initializer);
       
  2731         }
       
  2732 
       
  2733         if (parseObjCContextKeyword(Token_in, ast->in_token)) {
       
  2734             blockErrors(blocked);
       
  2735 
       
  2736             parseExpression(ast->fast_enumeratable_expression);
       
  2737             match(T_RPAREN, &ast->rparen_token);
       
  2738             parseStatement(ast->statement);
       
  2739 
       
  2740             node = ast;
       
  2741             return true;
       
  2742         }
       
  2743 
       
  2744         // there was no "in" token, so we continue with a normal for-statement
       
  2745         rewind(startOfTypeSpecifier);
       
  2746     }
       
  2747 
       
  2748     blockErrors(blocked);
       
  2749 
       
  2750     // Normal C/C++ for-statement parsing
       
  2751     ForStatementAST *ast = new (_pool) ForStatementAST;
       
  2752 
       
  2753     ast->for_token = for_token;
       
  2754     ast->lparen_token = lparen_token;
       
  2755     parseForInitStatement(ast->initializer);
       
  2756     parseCondition(ast->condition);
       
  2757     match(T_SEMICOLON, &ast->semicolon_token);
       
  2758     parseExpression(ast->expression);
       
  2759     match(T_RPAREN, &ast->rparen_token);
       
  2760     parseStatement(ast->statement);
       
  2761 
       
  2762     node = ast;
       
  2763     return true;
       
  2764 }
       
  2765 
       
  2766 bool Parser::parseForInitStatement(StatementAST *&node)
       
  2767 {
       
  2768     DEBUG_THIS_RULE();
       
  2769     return parseExpressionOrDeclarationStatement(node);
       
  2770 }
       
  2771 
       
  2772 bool Parser::parseCompoundStatement(StatementAST *&node)
       
  2773 {
       
  2774     DEBUG_THIS_RULE();
       
  2775     if (LA() == T_LBRACE) {
       
  2776         CompoundStatementAST *ast = new (_pool) CompoundStatementAST;
       
  2777         ast->lbrace_token = consumeToken();
       
  2778 
       
  2779         // ### TODO: the GNU "local label" extension: "__label__ X, Y, Z;"
       
  2780         // These are only allowed at the start of a compound stmt regardless of the language.
       
  2781 
       
  2782         StatementListAST **statement_ptr = &ast->statement_list;
       
  2783         while (int tk = LA()) {
       
  2784             if (tk == T_RBRACE)
       
  2785                 break;
       
  2786 
       
  2787             unsigned start_statement = cursor();
       
  2788             StatementAST *statement = 0;
       
  2789             if (! parseStatement(statement)) {
       
  2790                 rewind(start_statement + 1);
       
  2791                 skipUntilStatement();
       
  2792             } else {
       
  2793                 *statement_ptr = new (_pool) StatementListAST;
       
  2794                 (*statement_ptr)->value = statement;
       
  2795                 statement_ptr = &(*statement_ptr)->next;
       
  2796             }
       
  2797         }
       
  2798         match(T_RBRACE, &ast->rbrace_token);
       
  2799         node = ast;
       
  2800         return true;
       
  2801     }
       
  2802     return false;
       
  2803 }
       
  2804 
       
  2805 bool Parser::parseIfStatement(StatementAST *&node)
       
  2806 {
       
  2807     DEBUG_THIS_RULE();
       
  2808     if (LA() == T_IF) {
       
  2809         IfStatementAST *ast = new (_pool) IfStatementAST;
       
  2810         ast->if_token = consumeToken();
       
  2811         match(T_LPAREN, &ast->lparen_token);
       
  2812         parseCondition(ast->condition);
       
  2813         match(T_RPAREN, &ast->rparen_token);
       
  2814         if (! parseStatement(ast->statement))
       
  2815             _translationUnit->error(cursor(), "expected statement");
       
  2816         if (LA() == T_ELSE) {
       
  2817             ast->else_token = consumeToken();
       
  2818             if (! parseStatement(ast->else_statement))
       
  2819                 _translationUnit->error(cursor(), "expected statement");
       
  2820         }
       
  2821         node = ast;
       
  2822         return true;
       
  2823     }
       
  2824     return false;
       
  2825 }
       
  2826 
       
  2827 bool Parser::parseSwitchStatement(StatementAST *&node)
       
  2828 {
       
  2829     DEBUG_THIS_RULE();
       
  2830     if (LA() == T_SWITCH) {
       
  2831         SwitchStatementAST *ast = new (_pool) SwitchStatementAST;
       
  2832         ast->switch_token = consumeToken();
       
  2833         match(T_LPAREN, &ast->lparen_token);
       
  2834         parseCondition(ast->condition);
       
  2835         match(T_RPAREN, &ast->rparen_token);
       
  2836         parseStatement(ast->statement);
       
  2837         node = ast;
       
  2838         return true;
       
  2839     }
       
  2840     return false;
       
  2841 }
       
  2842 
       
  2843 bool Parser::parseLabeledStatement(StatementAST *&node)
       
  2844 {
       
  2845     DEBUG_THIS_RULE();
       
  2846     switch (LA()) {
       
  2847     case T_IDENTIFIER:
       
  2848         if (LA(2) == T_COLON) {
       
  2849             LabeledStatementAST *ast = new (_pool) LabeledStatementAST;
       
  2850             ast->label_token = consumeToken();
       
  2851             ast->colon_token = consumeToken();
       
  2852             parseStatement(ast->statement);
       
  2853             node = ast;
       
  2854             return true;
       
  2855         }
       
  2856         break;
       
  2857 
       
  2858     case T_DEFAULT: {
       
  2859         LabeledStatementAST *ast = new (_pool) LabeledStatementAST;
       
  2860         ast->label_token = consumeToken();
       
  2861         match(T_COLON, &ast->colon_token);
       
  2862         parseStatement(ast->statement);
       
  2863         node = ast;
       
  2864         return true;
       
  2865     }
       
  2866 
       
  2867     case T_CASE: {
       
  2868         CaseStatementAST *ast = new (_pool) CaseStatementAST;
       
  2869         ast->case_token = consumeToken();
       
  2870         parseConstantExpression(ast->expression);
       
  2871         match(T_COLON, &ast->colon_token);
       
  2872         parseStatement(ast->statement);
       
  2873         node = ast;
       
  2874         return true;
       
  2875     }
       
  2876 
       
  2877     default:
       
  2878         break;
       
  2879     } // switch
       
  2880     return false;
       
  2881 }
       
  2882 
       
  2883 bool Parser::parseBlockDeclaration(DeclarationAST *&node)
       
  2884 {
       
  2885     DEBUG_THIS_RULE();
       
  2886     switch (LA()) {
       
  2887     case T_USING:
       
  2888         return parseUsing(node);
       
  2889 
       
  2890     case T_ASM:
       
  2891         return parseAsmDefinition(node);
       
  2892 
       
  2893     case T_NAMESPACE:
       
  2894         return parseNamespaceAliasDefinition(node);
       
  2895 
       
  2896     default:
       
  2897         return parseSimpleDeclaration(node);
       
  2898     } // switch
       
  2899 
       
  2900 }
       
  2901 
       
  2902 bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
       
  2903 {
       
  2904     DEBUG_THIS_RULE();
       
  2905     if (LA() == T_NAMESPACE && LA(2) == T_IDENTIFIER && LA(3) == T_EQUAL) {
       
  2906         NamespaceAliasDefinitionAST *ast = new (_pool) NamespaceAliasDefinitionAST;
       
  2907         ast->namespace_token = consumeToken();
       
  2908         ast->namespace_name_token = consumeToken();
       
  2909         ast->equal_token = consumeToken();
       
  2910         parseName(ast->name);
       
  2911         match(T_SEMICOLON, &ast->semicolon_token);
       
  2912         node = ast;
       
  2913         return true;
       
  2914     }
       
  2915     return false;
       
  2916 }
       
  2917 
       
  2918 bool Parser::parseDeclarationStatement(StatementAST *&node)
       
  2919 {
       
  2920     DEBUG_THIS_RULE();
       
  2921     unsigned start = cursor();
       
  2922     DeclarationAST *declaration = 0;
       
  2923     if (! parseBlockDeclaration(declaration))
       
  2924         return false;
       
  2925 
       
  2926     if (SimpleDeclarationAST *simpleDeclaration = declaration->asSimpleDeclaration()) {
       
  2927         if (! simpleDeclaration->decl_specifier_list) {
       
  2928             rewind(start);
       
  2929             return false;
       
  2930         }
       
  2931     }
       
  2932 
       
  2933     DeclarationStatementAST *ast = new (_pool) DeclarationStatementAST;
       
  2934     ast->declaration = declaration;
       
  2935     node = ast;
       
  2936     return true;
       
  2937 }
       
  2938 
       
  2939 bool Parser::lookAtCVQualifier() const
       
  2940 {
       
  2941     switch (LA()) {
       
  2942     case T_CONST:
       
  2943     case T_VOLATILE:
       
  2944         return true;
       
  2945     default:
       
  2946         return false;
       
  2947     }
       
  2948 }
       
  2949 
       
  2950 bool Parser::lookAtFunctionSpecifier() const
       
  2951 {
       
  2952     switch (LA()) {
       
  2953     case T_INLINE:
       
  2954     case T_VIRTUAL:
       
  2955     case T_EXPLICIT:
       
  2956         return true;
       
  2957     default:
       
  2958         return false;
       
  2959     }
       
  2960 }
       
  2961 
       
  2962 bool Parser::lookAtStorageClassSpecifier() const
       
  2963 {
       
  2964     switch (LA()) {
       
  2965     case T_FRIEND:
       
  2966     case T_AUTO:
       
  2967     case T_REGISTER:
       
  2968     case T_STATIC:
       
  2969     case T_EXTERN:
       
  2970     case T_MUTABLE:
       
  2971     case T_TYPEDEF:
       
  2972         return true;
       
  2973     default:
       
  2974         return false;
       
  2975     }
       
  2976 }
       
  2977 
       
  2978 bool Parser::lookAtBuiltinTypeSpecifier() const
       
  2979 {
       
  2980     switch (LA()) {
       
  2981     case T_CHAR:
       
  2982     case T_WCHAR_T:
       
  2983     case T_BOOL:
       
  2984     case T_SHORT:
       
  2985     case T_INT:
       
  2986     case T_LONG:
       
  2987     case T_SIGNED:
       
  2988     case T_UNSIGNED:
       
  2989     case T_FLOAT:
       
  2990     case T_DOUBLE:
       
  2991     case T_VOID:
       
  2992         return true;
       
  2993     // [gcc] extensions
       
  2994     case T___TYPEOF__:
       
  2995     case T___ATTRIBUTE__:
       
  2996         return true;
       
  2997     default:
       
  2998         return false;
       
  2999     }
       
  3000 }
       
  3001 
       
  3002 bool Parser::lookAtClassKey() const
       
  3003 {
       
  3004     switch (LA()) {
       
  3005     case T_CLASS:
       
  3006     case T_STRUCT:
       
  3007     case T_UNION:
       
  3008         return true;
       
  3009     default:
       
  3010         return false;
       
  3011     }
       
  3012 }
       
  3013 
       
  3014 bool Parser::parseAttributeSpecifier(SpecifierListAST *&node)
       
  3015 {
       
  3016     DEBUG_THIS_RULE();
       
  3017     if (LA() != T___ATTRIBUTE__)
       
  3018         return false;
       
  3019 
       
  3020     AttributeSpecifierAST *ast = new (_pool) AttributeSpecifierAST;
       
  3021     ast->attribute_token = consumeToken();
       
  3022     match(T_LPAREN, &ast->first_lparen_token);
       
  3023     match(T_LPAREN, &ast->second_lparen_token);
       
  3024     parseAttributeList(ast->attribute_list);
       
  3025     match(T_RPAREN, &ast->first_rparen_token);
       
  3026     match(T_RPAREN, &ast->second_rparen_token);
       
  3027     node = new (_pool) SpecifierListAST(ast);
       
  3028     return true;
       
  3029 }
       
  3030 
       
  3031 bool Parser::parseAttributeList(AttributeListAST *&node)
       
  3032 {
       
  3033     DEBUG_THIS_RULE();
       
  3034 
       
  3035     AttributeListAST **iter = &node;
       
  3036     while (LA() == T_CONST || LA() == T_IDENTIFIER) {
       
  3037         *iter = new (_pool) AttributeListAST;
       
  3038 
       
  3039         if (LA() == T_CONST) {
       
  3040             AttributeAST *attr = new (_pool) AttributeAST;
       
  3041             attr->identifier_token = consumeToken();
       
  3042 
       
  3043             (*iter)->value = attr;
       
  3044             iter = &(*iter)->next;
       
  3045         } else if (LA() == T_IDENTIFIER) {
       
  3046             AttributeAST *attr = new (_pool) AttributeAST;
       
  3047             attr->identifier_token = consumeToken();
       
  3048             if (LA() == T_LPAREN) {
       
  3049                 attr->lparen_token = consumeToken();
       
  3050                 parseExpressionList(attr->expression_list);
       
  3051                 match(T_RPAREN, &attr->rparen_token);
       
  3052             }
       
  3053 
       
  3054             (*iter)->value = attr;
       
  3055             iter = &(*iter)->next;
       
  3056         }
       
  3057 
       
  3058         if (LA() != T_COMMA)
       
  3059             break;
       
  3060 
       
  3061         consumeToken(); // skip T_COMMA
       
  3062     }
       
  3063 
       
  3064     return true;
       
  3065 }
       
  3066 
       
  3067 bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node)
       
  3068 {
       
  3069     DEBUG_THIS_RULE();
       
  3070     if (LA() == T___ATTRIBUTE__) {
       
  3071         return parseAttributeSpecifier(node);
       
  3072     } else if (LA() == T___TYPEOF__) {
       
  3073         TypeofSpecifierAST *ast = new (_pool) TypeofSpecifierAST;
       
  3074         ast->typeof_token = consumeToken();
       
  3075         if (LA() == T_LPAREN) {
       
  3076             unsigned lparen_token = consumeToken();
       
  3077             if (parseTypeId(ast->expression) && LA() == T_RPAREN) {
       
  3078                 ast->lparen_token = lparen_token;
       
  3079                 ast->rparen_token = consumeToken();
       
  3080                 node = new (_pool) SpecifierListAST(ast);
       
  3081                 return true;
       
  3082             }
       
  3083             rewind(lparen_token);
       
  3084         }
       
  3085         parseUnaryExpression(ast->expression);
       
  3086         node = new (_pool) SpecifierListAST(ast);
       
  3087         return true;
       
  3088     } else if (lookAtBuiltinTypeSpecifier()) {
       
  3089         SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST;
       
  3090         ast->specifier_token = consumeToken();
       
  3091         node = new (_pool) SpecifierListAST(ast);
       
  3092         return true;
       
  3093     }
       
  3094     return false;
       
  3095 }
       
  3096 
       
  3097 bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
       
  3098                                     bool acceptStructDeclarator)
       
  3099 {
       
  3100     DEBUG_THIS_RULE();
       
  3101     unsigned qt_invokable_token = 0;
       
  3102     if (acceptStructDeclarator && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT))
       
  3103         qt_invokable_token = consumeToken();
       
  3104 #ifdef ICHECK_BUILD
       
  3105     unsigned invoke_token = 0;
       
  3106     if (LA() == T_Q_INVOKABLE)
       
  3107         invoke_token = consumeToken();
       
  3108 #endif
       
  3109 
       
  3110     // parse a simple declaration, a function definition,
       
  3111     // or a contructor declaration.
       
  3112     bool has_type_specifier = false;
       
  3113     bool has_complex_type_specifier = false;
       
  3114     unsigned startOfNamedTypeSpecifier = 0;
       
  3115     NameAST *named_type_specifier = 0;
       
  3116     SpecifierListAST *decl_specifier_seq = 0,
       
  3117          **decl_specifier_seq_ptr = &decl_specifier_seq;
       
  3118     for (;;) {
       
  3119         if (lookAtCVQualifier() || lookAtFunctionSpecifier()
       
  3120                 || lookAtStorageClassSpecifier()) {
       
  3121             SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
       
  3122             spec->specifier_token = consumeToken();
       
  3123             *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
       
  3124             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3125         } else if (LA() == T___ATTRIBUTE__) {
       
  3126             parseAttributeSpecifier(*decl_specifier_seq_ptr);
       
  3127             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3128         } else if (! named_type_specifier && ! has_complex_type_specifier && lookAtBuiltinTypeSpecifier()) {
       
  3129             parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr);
       
  3130             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3131             has_type_specifier = true;
       
  3132         } else if (! has_type_specifier && (LA() == T_COLON_COLON ||
       
  3133                                             LA() == T_IDENTIFIER)) {
       
  3134             startOfNamedTypeSpecifier = cursor();
       
  3135             if (parseName(named_type_specifier)) {
       
  3136                 NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST;
       
  3137                 spec->name = named_type_specifier;
       
  3138                 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
       
  3139                 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3140                 has_type_specifier = true;
       
  3141             } else {
       
  3142                 rewind(startOfNamedTypeSpecifier);
       
  3143                 break;
       
  3144             }
       
  3145         } else if (! has_type_specifier && LA() == T_ENUM) {
       
  3146             unsigned startOfTypeSpecifier = cursor();
       
  3147             if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) || LA() == T_LBRACE) {
       
  3148                 rewind(startOfTypeSpecifier);
       
  3149                 if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) {
       
  3150                     _translationUnit->error(startOfTypeSpecifier,
       
  3151                                             "expected an enum specifier");
       
  3152                     break;
       
  3153                 }
       
  3154                 has_complex_type_specifier = true;
       
  3155             }
       
  3156             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3157             has_type_specifier = true;
       
  3158         } else if (! has_type_specifier && LA() == T_TYPENAME) {
       
  3159             unsigned startOfElaboratedTypeSpecifier = cursor();
       
  3160             if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
       
  3161                 _translationUnit->error(startOfElaboratedTypeSpecifier,
       
  3162                                         "expected an elaborated type specifier");
       
  3163                 break;
       
  3164             }
       
  3165             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3166             has_type_specifier = true;
       
  3167         } else if (! has_type_specifier && lookAtClassKey()) {
       
  3168             unsigned startOfTypeSpecifier = cursor();
       
  3169             if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) ||
       
  3170                 (LA() == T_COLON || LA() == T_LBRACE || (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER &&
       
  3171                                                          (LA(2) == T_COLON || LA(2) == T_LBRACE)))) {
       
  3172                 rewind(startOfTypeSpecifier);
       
  3173                 if (! parseClassSpecifier(*decl_specifier_seq_ptr)) {
       
  3174                     _translationUnit->error(startOfTypeSpecifier,
       
  3175                                             "wrong type specifier");
       
  3176                     break;
       
  3177                 }
       
  3178                 has_complex_type_specifier = true;
       
  3179             }
       
  3180             decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
       
  3181             has_type_specifier = true;
       
  3182         } else
       
  3183             break;
       
  3184     }
       
  3185 
       
  3186     DeclaratorListAST *declarator_list = 0,
       
  3187         **declarator_ptr = &declarator_list;
       
  3188 
       
  3189     DeclaratorAST *declarator = 0;
       
  3190 
       
  3191     if (LA() != T_SEMICOLON) {
       
  3192         const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier);
       
  3193         if (! parseInitDeclarator(declarator, acceptStructDeclarator) && maybeCtor) {
       
  3194             rewind(startOfNamedTypeSpecifier);
       
  3195             named_type_specifier = 0;
       
  3196             // pop the named type specifier from the decl-specifier-seq
       
  3197             SpecifierListAST **spec_ptr = &decl_specifier_seq;
       
  3198             for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) {
       
  3199                 if (! (*spec_ptr)->next) {
       
  3200                     *spec_ptr = 0;
       
  3201                     break;
       
  3202                 }
       
  3203             }
       
  3204             if (! parseInitDeclarator(declarator, acceptStructDeclarator))
       
  3205                 return false;
       
  3206         }
       
  3207     }
       
  3208 
       
  3209     // if there is no valid declarator
       
  3210     // and it doesn't look like a fwd or a class declaration
       
  3211     // then it's not a declarations
       
  3212     if (! declarator && ! maybeForwardOrClassDeclaration(decl_specifier_seq))
       
  3213         return false;
       
  3214 
       
  3215     DeclaratorAST *firstDeclarator = declarator;
       
  3216 
       
  3217     if (declarator) {
       
  3218         *declarator_ptr = new (_pool) DeclaratorListAST;
       
  3219         (*declarator_ptr)->value = declarator;
       
  3220         declarator_ptr = &(*declarator_ptr)->next;
       
  3221     }
       
  3222 
       
  3223     if (LA() == T_COMMA || LA() == T_SEMICOLON || has_complex_type_specifier) {
       
  3224         while (LA() == T_COMMA) {
       
  3225             consumeToken(); // consume T_COMMA
       
  3226 
       
  3227             declarator = 0;
       
  3228             if (parseInitDeclarator(declarator, acceptStructDeclarator)) {
       
  3229                 *declarator_ptr = new (_pool) DeclaratorListAST;
       
  3230                 (*declarator_ptr)->value = declarator;
       
  3231                 declarator_ptr = &(*declarator_ptr)->next;
       
  3232             }
       
  3233         }
       
  3234         SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST;
       
  3235         ast->qt_invokable_token = qt_invokable_token;
       
  3236 #ifdef ICHECK_BUILD
       
  3237         ast->invoke_token = invoke_token;
       
  3238 #endif
       
  3239         ast->decl_specifier_list = decl_specifier_seq;
       
  3240         ast->declarator_list = declarator_list;
       
  3241         match(T_SEMICOLON, &ast->semicolon_token);
       
  3242         node = ast;
       
  3243         return true;
       
  3244     } else if (! _inFunctionBody && declarator && (LA() == T_COLON || LA() == T_LBRACE || LA() == T_TRY)) {
       
  3245         CtorInitializerAST *ctor_initializer = 0;
       
  3246         bool hasCtorInitializer = false;
       
  3247         if (LA() == T_COLON) {
       
  3248             hasCtorInitializer = true;
       
  3249             parseCtorInitializer(ctor_initializer);
       
  3250 
       
  3251             if (LA() != T_LBRACE) {
       
  3252                 const unsigned pos = cursor();
       
  3253 
       
  3254                 for (int n = 0; n < 3 && LA(); consumeToken(), ++n)
       
  3255                     if (LA() == T_LBRACE)
       
  3256                         break;
       
  3257 
       
  3258                 if (LA() != T_LBRACE) {
       
  3259                     _translationUnit->error(pos, "unexpected token `%s'", _translationUnit->spell(pos));
       
  3260                     rewind(pos);
       
  3261                 }
       
  3262             }
       
  3263         }
       
  3264 
       
  3265         if (LA() == T_LBRACE || hasCtorInitializer) {
       
  3266             FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
       
  3267             ast->qt_invokable_token = qt_invokable_token;
       
  3268 #ifdef ICHECK_BUILD
       
  3269             ast->invoke_token = invoke_token;
       
  3270 #endif
       
  3271             ast->decl_specifier_list = decl_specifier_seq;
       
  3272             ast->declarator = firstDeclarator;
       
  3273             ast->ctor_initializer = ctor_initializer;
       
  3274             parseFunctionBody(ast->function_body);
       
  3275             node = ast;
       
  3276             return true; // recognized a function definition.
       
  3277         } else if (LA() == T_TRY) {
       
  3278             FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
       
  3279             ast->qt_invokable_token = qt_invokable_token;
       
  3280 #ifdef ICHECK_BUILD
       
  3281             ast->invoke_token = invoke_token;
       
  3282 #endif
       
  3283             ast->decl_specifier_list = decl_specifier_seq;
       
  3284             ast->declarator = firstDeclarator;
       
  3285             ast->ctor_initializer = ctor_initializer;
       
  3286             parseTryBlockStatement(ast->function_body);
       
  3287             node = ast;
       
  3288             return true; // recognized a function definition.
       
  3289         }
       
  3290     }
       
  3291 
       
  3292     _translationUnit->error(cursor(), "unexpected token `%s'", tok().spell());
       
  3293     return false;
       
  3294 }
       
  3295 
       
  3296 bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const
       
  3297 {
       
  3298     // look at the decl_specifier for possible fwd or class declarations.
       
  3299     if (SpecifierListAST *it = decl_specifier_seq) {
       
  3300         while (it) {
       
  3301             SimpleSpecifierAST *spec = it->value->asSimpleSpecifier();
       
  3302             if (spec && _translationUnit->tokenKind(spec->specifier_token) == T_FRIEND)
       
  3303                 it = it->next;
       
  3304             else
       
  3305                 break;
       
  3306         }
       
  3307 
       
  3308         if (it) {
       
  3309             SpecifierAST *spec = it->value;
       
  3310 
       
  3311             if (! it->next && (spec->asElaboratedTypeSpecifier() ||
       
  3312                                spec->asEnumSpecifier() ||
       
  3313                                spec->asClassSpecifier()))
       
  3314                 return true;
       
  3315         }
       
  3316     }
       
  3317 
       
  3318     return false;
       
  3319 }
       
  3320 
       
  3321 bool Parser::parseFunctionBody(StatementAST *&node)
       
  3322 {
       
  3323     DEBUG_THIS_RULE();
       
  3324     if (_translationUnit->skipFunctionBody()) {
       
  3325         unsigned token_lbrace = 0;
       
  3326         match(T_LBRACE, &token_lbrace);
       
  3327         if (! token_lbrace)
       
  3328             return false;
       
  3329 
       
  3330         const Token &tk = _translationUnit->tokenAt(token_lbrace);
       
  3331         if (tk.close_brace)
       
  3332             rewind(tk.close_brace);
       
  3333         unsigned token_rbrace = 0;
       
  3334         match(T_RBRACE, &token_rbrace);
       
  3335         return true;
       
  3336     }
       
  3337 
       
  3338     _inFunctionBody = true;
       
  3339     const bool parsed = parseCompoundStatement(node);
       
  3340     _inFunctionBody = false;
       
  3341     return parsed;
       
  3342 }
       
  3343 
       
  3344 bool Parser::parseTryBlockStatement(StatementAST *&node)
       
  3345 {
       
  3346     DEBUG_THIS_RULE();
       
  3347     if (LA() == T_TRY) {
       
  3348         TryBlockStatementAST *ast = new (_pool) TryBlockStatementAST;
       
  3349         ast->try_token = consumeToken();
       
  3350         parseCompoundStatement(ast->statement);
       
  3351         CatchClauseListAST **catch_clause_ptr = &ast->catch_clause_list;
       
  3352         while (parseCatchClause(*catch_clause_ptr))
       
  3353             catch_clause_ptr = &(*catch_clause_ptr)->next;
       
  3354         node = ast;
       
  3355         return true;
       
  3356     }
       
  3357     return false;
       
  3358 }
       
  3359 
       
  3360 bool Parser::parseCatchClause(CatchClauseListAST *&node)
       
  3361 {
       
  3362     DEBUG_THIS_RULE();
       
  3363     if (LA() == T_CATCH) {
       
  3364         CatchClauseAST *ast = new (_pool) CatchClauseAST;
       
  3365         ast->catch_token = consumeToken();
       
  3366         match(T_LPAREN, &ast->lparen_token);
       
  3367         parseExceptionDeclaration(ast->exception_declaration);
       
  3368         match(T_RPAREN, &ast->rparen_token);
       
  3369         parseCompoundStatement(ast->statement);
       
  3370         node = new (_pool) CatchClauseListAST(ast);
       
  3371         return true;
       
  3372     }
       
  3373     return false;
       
  3374 }
       
  3375 
       
  3376 bool Parser::parseExceptionDeclaration(ExceptionDeclarationAST *&node)
       
  3377 {
       
  3378     DEBUG_THIS_RULE();
       
  3379     if (LA() == T_DOT_DOT_DOT) {
       
  3380         ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST;
       
  3381         ast->dot_dot_dot_token = consumeToken();
       
  3382         node = ast;
       
  3383         return true;
       
  3384     }
       
  3385 
       
  3386     SpecifierListAST *type_specifier = 0;
       
  3387     if (parseTypeSpecifier(type_specifier)) {
       
  3388         ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST;
       
  3389         ast->type_specifier_list = type_specifier;
       
  3390         parseDeclaratorOrAbstractDeclarator(ast->declarator);
       
  3391         node = ast;
       
  3392         return true;
       
  3393     }
       
  3394     return false;
       
  3395 }
       
  3396 
       
  3397 bool Parser::parseBoolLiteral(ExpressionAST *&node)
       
  3398 {
       
  3399     DEBUG_THIS_RULE();
       
  3400     if (LA() == T_TRUE || LA() == T_FALSE) {
       
  3401         BoolLiteralAST *ast = new (_pool) BoolLiteralAST;
       
  3402         ast->literal_token = consumeToken();
       
  3403         node = ast;
       
  3404         return true;
       
  3405     }
       
  3406     return false;
       
  3407 }
       
  3408 
       
  3409 bool Parser::parseNumericLiteral(ExpressionAST *&node)
       
  3410 {
       
  3411     DEBUG_THIS_RULE();
       
  3412     if (LA() == T_NUMERIC_LITERAL  ||
       
  3413         LA() == T_CHAR_LITERAL     ||
       
  3414         LA() == T_WIDE_CHAR_LITERAL) {
       
  3415         NumericLiteralAST *ast = new (_pool) NumericLiteralAST;
       
  3416         ast->literal_token = consumeToken();
       
  3417         node = ast;
       
  3418         return true;
       
  3419     }
       
  3420     return false;
       
  3421 }
       
  3422 
       
  3423 bool Parser::parseThisExpression(ExpressionAST *&node)
       
  3424 {
       
  3425     DEBUG_THIS_RULE();
       
  3426     if (LA() == T_THIS) {
       
  3427         ThisExpressionAST *ast = new (_pool) ThisExpressionAST;
       
  3428         ast->this_token = consumeToken();
       
  3429         node = ast;
       
  3430         return true;
       
  3431     }
       
  3432     return false;
       
  3433 }
       
  3434 
       
  3435 bool Parser::parsePrimaryExpression(ExpressionAST *&node)
       
  3436 {
       
  3437     DEBUG_THIS_RULE();
       
  3438     switch (LA()) {
       
  3439     case T_STRING_LITERAL:
       
  3440     case T_WIDE_STRING_LITERAL:
       
  3441         return parseStringLiteral(node);
       
  3442 
       
  3443     case T_CHAR_LITERAL: // ### FIXME don't use NumericLiteral for chars
       
  3444     case T_WIDE_CHAR_LITERAL:
       
  3445     case T_NUMERIC_LITERAL:
       
  3446         return parseNumericLiteral(node);
       
  3447 
       
  3448     case T_TRUE:
       
  3449     case T_FALSE:
       
  3450         return parseBoolLiteral(node);
       
  3451 
       
  3452     case T_THIS:
       
  3453         return parseThisExpression(node);
       
  3454 
       
  3455     case T_LPAREN:
       
  3456         return parseNestedExpression(node);
       
  3457 
       
  3458     case T_SIGNAL:
       
  3459     case T_SLOT:
       
  3460         return parseQtMethod(node);
       
  3461 
       
  3462     case T_LBRACKET:
       
  3463     case T_AT_STRING_LITERAL:
       
  3464     case T_AT_ENCODE:
       
  3465     case T_AT_PROTOCOL:
       
  3466     case T_AT_SELECTOR:
       
  3467         return parseObjCExpression(node);
       
  3468 
       
  3469     default: {
       
  3470         NameAST *name = 0;
       
  3471         if (parseNameId(name)) {
       
  3472             node = name;
       
  3473             return true;
       
  3474         }
       
  3475         break;
       
  3476     } // default
       
  3477 
       
  3478     } // switch
       
  3479 
       
  3480     return false;
       
  3481 }
       
  3482 
       
  3483 bool Parser::parseObjCExpression(ExpressionAST *&node)
       
  3484 {
       
  3485     DEBUG_THIS_RULE();
       
  3486     switch (LA()) {
       
  3487     case T_AT_ENCODE:
       
  3488         return parseObjCEncodeExpression(node);
       
  3489 
       
  3490     case T_AT_PROTOCOL:
       
  3491         return parseObjCProtocolExpression(node);
       
  3492 
       
  3493     case T_AT_SELECTOR:
       
  3494         return parseObjCSelectorExpression(node);
       
  3495 
       
  3496     case T_LBRACKET:
       
  3497         return parseObjCMessageExpression(node);
       
  3498 
       
  3499     case T_AT_STRING_LITERAL:
       
  3500         return parseObjCStringLiteral(node);
       
  3501 
       
  3502     default:
       
  3503         break;
       
  3504     } // switch
       
  3505     return false;
       
  3506 }
       
  3507 
       
  3508 bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
       
  3509 {
       
  3510     DEBUG_THIS_RULE();
       
  3511     if (LA() != T_AT_STRING_LITERAL)
       
  3512         return false;
       
  3513 
       
  3514     StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
       
  3515 
       
  3516     while (LA() == T_AT_STRING_LITERAL) {
       
  3517         *ast = new (_pool) StringLiteralAST;
       
  3518         (*ast)->literal_token = consumeToken();
       
  3519         ast = &(*ast)->next;
       
  3520     }
       
  3521     return true;
       
  3522 }
       
  3523 
       
  3524 bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
       
  3525 {
       
  3526     DEBUG_THIS_RULE();
       
  3527     if (LA() != T_AT_SYNCHRONIZED)
       
  3528         return false;
       
  3529 
       
  3530     ObjCSynchronizedStatementAST *ast = new (_pool) ObjCSynchronizedStatementAST;
       
  3531 
       
  3532     ast->synchronized_token = consumeToken();
       
  3533     match(T_LPAREN, &ast->lparen_token);
       
  3534     parseExpression(ast->synchronized_object);
       
  3535     match(T_RPAREN, &ast->rparen_token);
       
  3536     parseStatement(ast->statement);
       
  3537 
       
  3538     node = ast;
       
  3539     return true;
       
  3540 }
       
  3541 
       
  3542 bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
       
  3543 {
       
  3544     DEBUG_THIS_RULE();
       
  3545     if (LA() != T_AT_ENCODE)
       
  3546         return false;
       
  3547 
       
  3548     ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
       
  3549     ast->encode_token = consumeToken();
       
  3550     parseObjCTypeName(ast->type_name);
       
  3551     node = ast;
       
  3552     return true;
       
  3553 }
       
  3554 
       
  3555 bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
       
  3556 {
       
  3557     DEBUG_THIS_RULE();
       
  3558     if (LA() != T_AT_PROTOCOL)
       
  3559         return false;
       
  3560 
       
  3561     ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST;
       
  3562     ast->protocol_token = consumeToken();
       
  3563     match(T_LPAREN, &ast->lparen_token);
       
  3564     match(T_IDENTIFIER, &ast->identifier_token);
       
  3565     match(T_RPAREN, &ast->rparen_token);
       
  3566     node = ast;
       
  3567     return true;
       
  3568 }
       
  3569 
       
  3570 bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
       
  3571 {
       
  3572     DEBUG_THIS_RULE();
       
  3573     if (LA() != T_AT_SELECTOR)
       
  3574         return false;
       
  3575 
       
  3576     ObjCSelectorExpressionAST *ast = new (_pool) ObjCSelectorExpressionAST;
       
  3577     ast->selector_token = consumeToken();
       
  3578     match(T_LPAREN, &ast->lparen_token);
       
  3579 
       
  3580     unsigned identifier_token = 0;
       
  3581     match(T_IDENTIFIER, &identifier_token);
       
  3582     if (LA() == T_COLON) {
       
  3583         ObjCSelectorWithArgumentsAST *args = new (_pool) ObjCSelectorWithArgumentsAST;
       
  3584         ast->selector = args;
       
  3585         ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST;
       
  3586         args->selector_argument_list = last;
       
  3587         last->value = new (_pool) ObjCSelectorArgumentAST;
       
  3588         last->value->name_token = identifier_token;
       
  3589         last->value->colon_token = consumeToken();
       
  3590 
       
  3591         while (LA() != T_RPAREN) {
       
  3592             last->next = new (_pool) ObjCSelectorArgumentListAST;
       
  3593             last = last->next;
       
  3594             last->value = new (_pool) ObjCSelectorArgumentAST;
       
  3595             match(T_IDENTIFIER, &last->value->name_token);
       
  3596             match(T_COLON, &last->value->colon_token);
       
  3597         }
       
  3598     } else {
       
  3599         ObjCSelectorWithoutArgumentsAST *args = new (_pool) ObjCSelectorWithoutArgumentsAST;
       
  3600         ast->selector = args;
       
  3601         args->name_token = identifier_token;
       
  3602     }
       
  3603 
       
  3604     match(T_RPAREN, &ast->rparen_token);
       
  3605     node = ast;
       
  3606     return true;
       
  3607 }
       
  3608 
       
  3609 bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
       
  3610 {
       
  3611     DEBUG_THIS_RULE();
       
  3612     if (LA() != T_LBRACKET)
       
  3613         return false;
       
  3614 
       
  3615     unsigned start = cursor();
       
  3616 
       
  3617     unsigned lbracket_token = consumeToken();
       
  3618     ExpressionAST *receiver_expression = 0;
       
  3619     ObjCSelectorAST *selector = 0;
       
  3620     ObjCMessageArgumentListAST *argument_list = 0;
       
  3621 
       
  3622     if (parseObjCMessageReceiver(receiver_expression) &&
       
  3623         parseObjCMessageArguments(selector, argument_list)) {
       
  3624 
       
  3625         ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
       
  3626         ast->lbracket_token = lbracket_token;
       
  3627         ast->receiver_expression = receiver_expression;
       
  3628         ast->selector = selector;
       
  3629         ast->argument_list = argument_list;
       
  3630 
       
  3631         match(T_RBRACKET, &ast->rbracket_token);
       
  3632         node = ast;
       
  3633 
       
  3634         return true;
       
  3635     }
       
  3636 
       
  3637     rewind(start);
       
  3638     return false;
       
  3639 }
       
  3640 
       
  3641 bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
       
  3642 {
       
  3643     DEBUG_THIS_RULE();
       
  3644     return parseExpression(node);
       
  3645 }
       
  3646 
       
  3647 bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArgumentListAST *& argNode)
       
  3648 {
       
  3649     DEBUG_THIS_RULE();
       
  3650     if (LA() == T_RBRACKET)
       
  3651         return false; // nothing to do.
       
  3652 
       
  3653     unsigned start = cursor();
       
  3654 
       
  3655     ObjCSelectorArgumentAST *selectorArgument = 0;
       
  3656     ObjCMessageArgumentAST *messageArgument = 0;
       
  3657 
       
  3658     if (parseObjCSelectorArg(selectorArgument, messageArgument)) {
       
  3659         ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST;
       
  3660         selAst->value = selectorArgument;
       
  3661         ObjCSelectorArgumentListAST *lastSelector = selAst;
       
  3662 
       
  3663         ObjCMessageArgumentListAST *argAst = new (_pool) ObjCMessageArgumentListAST;
       
  3664         argAst->value = messageArgument;
       
  3665         ObjCMessageArgumentListAST *lastArgument = argAst;
       
  3666 
       
  3667         while (parseObjCSelectorArg(selectorArgument, messageArgument)) {
       
  3668             // accept the selector args.
       
  3669             lastSelector->next = new (_pool) ObjCSelectorArgumentListAST;
       
  3670             lastSelector = lastSelector->next;
       
  3671             lastSelector->value = selectorArgument;
       
  3672 
       
  3673             lastArgument->next = new (_pool) ObjCMessageArgumentListAST;
       
  3674             lastArgument = lastArgument->next;
       
  3675             lastArgument->value = messageArgument;
       
  3676         }
       
  3677 
       
  3678         if (LA() == T_COMMA) {
       
  3679             ExpressionAST **lastExpression = &lastArgument->value->parameter_value_expression;
       
  3680 
       
  3681             while (LA() == T_COMMA) {
       
  3682                 BinaryExpressionAST *binaryExpression = new (_pool) BinaryExpressionAST;
       
  3683                 binaryExpression->left_expression = *lastExpression;
       
  3684                 binaryExpression->binary_op_token = consumeToken(); // T_COMMA
       
  3685                 parseAssignmentExpression(binaryExpression->right_expression);
       
  3686                 lastExpression = &binaryExpression->right_expression;
       
  3687             }
       
  3688         }
       
  3689 
       
  3690         ObjCSelectorWithArgumentsAST *selWithArgs = new (_pool) ObjCSelectorWithArgumentsAST;
       
  3691         selWithArgs->selector_argument_list = selAst;
       
  3692 
       
  3693         selNode = selWithArgs;
       
  3694         argNode = argAst;
       
  3695         return true;
       
  3696     } else {
       
  3697         rewind(start);
       
  3698         unsigned name_token = 0;
       
  3699         if (!parseObjCSelector(name_token))
       
  3700             return false;
       
  3701         ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
       
  3702         sel->name_token = name_token;
       
  3703         selNode = sel;
       
  3704         argNode = 0;
       
  3705         return true;
       
  3706     }
       
  3707 
       
  3708     return false;
       
  3709 }
       
  3710 
       
  3711 bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode)
       
  3712 {
       
  3713     DEBUG_THIS_RULE();
       
  3714     unsigned selector_token = 0;
       
  3715     if (!parseObjCSelector(selector_token))
       
  3716         return false;
       
  3717 
       
  3718     if (LA() != T_COLON)
       
  3719         return false;
       
  3720 
       
  3721     selNode = new (_pool) ObjCSelectorArgumentAST;
       
  3722     selNode->name_token = selector_token;
       
  3723     selNode->colon_token = consumeToken();
       
  3724 
       
  3725     argNode = new (_pool) ObjCMessageArgumentAST;
       
  3726     ExpressionAST **expr = &argNode->parameter_value_expression;
       
  3727     unsigned expressionStart = cursor();
       
  3728     if (parseAssignmentExpression(*expr) && LA() == T_COLON && (*expr)->asCastExpression()) {
       
  3729         rewind(expressionStart);
       
  3730         parseUnaryExpression(*expr);
       
  3731         //
       
  3732     }
       
  3733     return true;
       
  3734 }
       
  3735 
       
  3736 bool Parser::parseNameId(NameAST *&name)
       
  3737 {
       
  3738     DEBUG_THIS_RULE();
       
  3739     unsigned start = cursor();
       
  3740     if (! parseName(name))
       
  3741         return false;
       
  3742 
       
  3743     if (LA() == T_RPAREN || LA() == T_COMMA)
       
  3744         return true;
       
  3745 
       
  3746     QualifiedNameAST *qualified_name_id = name->asQualifiedName();
       
  3747 
       
  3748     TemplateIdAST *template_id = 0;
       
  3749     if (qualified_name_id) {
       
  3750         if (NameAST *unqualified_name = qualified_name_id->unqualified_name)
       
  3751             template_id = unqualified_name->asTemplateId();
       
  3752     } else {
       
  3753         template_id = name->asTemplateId();
       
  3754     }
       
  3755 
       
  3756     if (! template_id)
       
  3757         return true; // it's not a template-id, there's nothing to rewind.
       
  3758 
       
  3759     else if (LA() == T_LPAREN) {
       
  3760         // a template-id followed by a T_LPAREN
       
  3761         if (TemplateArgumentListAST *template_arguments = template_id->template_argument_list) {
       
  3762             if (! template_arguments->next && template_arguments->value &&
       
  3763                     template_arguments->value->asBinaryExpression()) {
       
  3764 
       
  3765                 unsigned saved = cursor();
       
  3766                 ExpressionAST *expr = 0;
       
  3767 
       
  3768                 bool blocked = blockErrors(true);
       
  3769                 bool lookAtCastExpression = parseCastExpression(expr);
       
  3770                 (void) blockErrors(blocked);
       
  3771 
       
  3772                 if (lookAtCastExpression) {
       
  3773                     if (CastExpressionAST *cast_expression = expr->asCastExpression()) {
       
  3774                         if (cast_expression->lparen_token && cast_expression->rparen_token
       
  3775                                 && cast_expression->type_id && cast_expression->expression) {
       
  3776                             rewind(start);
       
  3777 
       
  3778                             name = 0;
       
  3779                             return parseName(name, false);
       
  3780                         }
       
  3781                     }
       
  3782                 }
       
  3783                 rewind(saved);
       
  3784             }
       
  3785         }
       
  3786     }
       
  3787 
       
  3788     switch (LA()) {
       
  3789     case T_COMMA:
       
  3790     case T_SEMICOLON:
       
  3791     case T_LBRACKET:
       
  3792     case T_LPAREN:
       
  3793         return true;
       
  3794 
       
  3795     case T_IDENTIFIER:
       
  3796     case T_STATIC_CAST:
       
  3797     case T_DYNAMIC_CAST:
       
  3798     case T_REINTERPRET_CAST:
       
  3799     case T_CONST_CAST:
       
  3800         rewind(start);
       
  3801         return parseName(name, false);
       
  3802 
       
  3803     default:
       
  3804         if (tok().isLiteral() || tok().isOperator()) {
       
  3805             rewind(start);
       
  3806             return parseName(name, false);
       
  3807         }
       
  3808     } // switch
       
  3809 
       
  3810     return true;
       
  3811 }
       
  3812 
       
  3813 bool Parser::parseNestedExpression(ExpressionAST *&node)
       
  3814 {
       
  3815     DEBUG_THIS_RULE();
       
  3816     if (LA() == T_LPAREN) {
       
  3817         unsigned lparen_token = consumeToken();
       
  3818 
       
  3819         if (LA() == T_LBRACE) {
       
  3820             NestedExpressionAST *ast = new (_pool) NestedExpressionAST;
       
  3821             ast->lparen_token = lparen_token;
       
  3822 
       
  3823             // ### ast
       
  3824             StatementAST *statement = 0;
       
  3825             parseCompoundStatement(statement);
       
  3826             match(T_RPAREN, &ast->rparen_token);
       
  3827             node = ast;
       
  3828             return true;
       
  3829         }
       
  3830 
       
  3831         bool previousTemplateArguments = switchTemplateArguments(false);
       
  3832 
       
  3833         ExpressionAST *expression = 0;
       
  3834         if (parseExpression(expression) && LA() == T_RPAREN) {
       
  3835             NestedExpressionAST *ast = new (_pool) NestedExpressionAST;
       
  3836             ast->lparen_token = lparen_token;
       
  3837             ast->expression = expression;
       
  3838             ast->rparen_token = consumeToken();
       
  3839             node = ast;
       
  3840             (void) switchTemplateArguments(previousTemplateArguments);
       
  3841             return true;
       
  3842         }
       
  3843         (void) switchTemplateArguments(previousTemplateArguments);
       
  3844     }
       
  3845     return false;
       
  3846 }
       
  3847 
       
  3848 bool Parser::parseCppCastExpression(ExpressionAST *&node)
       
  3849 {
       
  3850     DEBUG_THIS_RULE();
       
  3851     if (LA() == T_DYNAMIC_CAST     || LA() == T_STATIC_CAST ||
       
  3852         LA() == T_REINTERPRET_CAST || LA() == T_CONST_CAST) {
       
  3853         CppCastExpressionAST *ast = new (_pool) CppCastExpressionAST;
       
  3854         ast->cast_token = consumeToken();
       
  3855         match(T_LESS, &ast->less_token);
       
  3856         parseTypeId(ast->type_id);
       
  3857         match(T_GREATER, &ast->greater_token);
       
  3858         match(T_LPAREN, &ast->lparen_token);
       
  3859         parseExpression(ast->expression);
       
  3860         match(T_RPAREN, &ast->rparen_token);
       
  3861         node = ast;
       
  3862         return true;
       
  3863     }
       
  3864     return false;
       
  3865 }
       
  3866 
       
  3867 // typename ::opt  nested-name-specifier identifier ( expression-listopt )
       
  3868 // typename ::opt  nested-name-specifier templateopt  template-id ( expression-listopt )
       
  3869 bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
       
  3870 {
       
  3871     DEBUG_THIS_RULE();
       
  3872     if (LA() == T_TYPENAME) {
       
  3873         unsigned typename_token = consumeToken();
       
  3874         NameAST *name = 0;
       
  3875         if (parseName(name) && LA() == T_LPAREN) {
       
  3876             TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST;
       
  3877             ast->typename_token = typename_token;
       
  3878             ast->name = name;
       
  3879             ast->lparen_token = consumeToken();
       
  3880             parseExpressionList(ast->expression_list);
       
  3881             match(T_RPAREN, &ast->rparen_token);
       
  3882             node = ast;
       
  3883             return true;
       
  3884         }
       
  3885     }
       
  3886     return false;
       
  3887 }
       
  3888 
       
  3889 // typeid ( expression )
       
  3890 // typeid ( type-id )
       
  3891 bool Parser::parseTypeidExpression(ExpressionAST *&node)
       
  3892 {
       
  3893     DEBUG_THIS_RULE();
       
  3894     if (LA() == T_TYPEID) {
       
  3895         TypeidExpressionAST *ast = new (_pool) TypeidExpressionAST;
       
  3896         ast->typeid_token = consumeToken();
       
  3897         if (LA() == T_LPAREN)
       
  3898             ast->lparen_token = consumeToken();
       
  3899         unsigned saved = cursor();
       
  3900         if (! (parseTypeId(ast->expression) && LA() == T_RPAREN)) {
       
  3901             rewind(saved);
       
  3902             parseExpression(ast->expression);
       
  3903         }
       
  3904         match(T_RPAREN, &ast->rparen_token);
       
  3905         node = ast;
       
  3906         return true;
       
  3907     }
       
  3908     return false;
       
  3909 }
       
  3910 
       
  3911 bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
       
  3912 {
       
  3913     DEBUG_THIS_RULE();
       
  3914 
       
  3915     switch (LA()) {
       
  3916     case T_DYNAMIC_CAST:
       
  3917     case T_STATIC_CAST:
       
  3918     case T_REINTERPRET_CAST:
       
  3919     case T_CONST_CAST:
       
  3920         return parseCppCastExpression(node);
       
  3921 
       
  3922     case T_TYPENAME:
       
  3923         return parseTypenameCallExpression(node);
       
  3924 
       
  3925     case T_TYPEID:
       
  3926         return parseTypeidExpression(node);
       
  3927 
       
  3928     default: {
       
  3929         unsigned start = cursor();
       
  3930         SpecifierListAST *type_specifier = 0;
       
  3931         bool blocked = blockErrors(true);
       
  3932         if (lookAtBuiltinTypeSpecifier() &&
       
  3933                 parseSimpleTypeSpecifier(type_specifier) &&
       
  3934                 LA() == T_LPAREN) {
       
  3935             unsigned lparen_token = consumeToken();
       
  3936             ExpressionListAST *expression_list = 0;
       
  3937             parseExpressionList(expression_list);
       
  3938             if (LA() == T_RPAREN) {
       
  3939                 unsigned rparen_token = consumeToken();
       
  3940                 TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST;
       
  3941                 ast->type_specifier_list = type_specifier;
       
  3942                 ast->lparen_token = lparen_token;
       
  3943                 ast->expression_list = expression_list;
       
  3944                 ast->rparen_token = rparen_token;
       
  3945                 node = ast;
       
  3946                 blockErrors(blocked);
       
  3947                 return true;
       
  3948             }
       
  3949         }
       
  3950         rewind(start);
       
  3951 
       
  3952         // look for compound literals
       
  3953         if (LA() == T_LPAREN) {
       
  3954             unsigned lparen_token = consumeToken();
       
  3955             ExpressionAST *type_id = 0;
       
  3956             if (parseTypeId(type_id) && LA() == T_RPAREN) {
       
  3957                 unsigned rparen_token = consumeToken();
       
  3958                 if (LA() == T_LBRACE) {
       
  3959                     blockErrors(blocked);
       
  3960 
       
  3961                     CompoundLiteralAST *ast = new (_pool) CompoundLiteralAST;
       
  3962                     ast->lparen_token = lparen_token;
       
  3963                     ast->type_id = type_id;
       
  3964                     ast->rparen_token = rparen_token;
       
  3965                     parseInitializerClause(ast->initializer);
       
  3966                     node = ast;
       
  3967                     return true;
       
  3968                 }
       
  3969             }
       
  3970             rewind(start);
       
  3971         }
       
  3972 
       
  3973         blockErrors(blocked);
       
  3974         return parsePrimaryExpression(node);
       
  3975     } // default
       
  3976     } // switch
       
  3977 }
       
  3978 
       
  3979 bool Parser::parsePostfixExpression(ExpressionAST *&node)
       
  3980 {
       
  3981     DEBUG_THIS_RULE();
       
  3982     if (parseCorePostfixExpression(node)) {
       
  3983         PostfixListAST *postfix_expressions = 0,
       
  3984             **postfix_ptr = &postfix_expressions;
       
  3985         while (LA()) {
       
  3986             if (LA() == T_LPAREN) {
       
  3987                 CallAST *ast = new (_pool) CallAST;
       
  3988                 ast->lparen_token = consumeToken();
       
  3989                 parseExpressionList(ast->expression_list);
       
  3990                 match(T_RPAREN, &ast->rparen_token);
       
  3991                 *postfix_ptr = new (_pool) PostfixListAST(ast);
       
  3992                 postfix_ptr = &(*postfix_ptr)->next;
       
  3993             } else if (LA() == T_LBRACKET) {
       
  3994                 ArrayAccessAST *ast = new (_pool) ArrayAccessAST;
       
  3995                 ast->lbracket_token = consumeToken();
       
  3996                 parseExpression(ast->expression);
       
  3997                 match(T_RBRACKET, &ast->rbracket_token);
       
  3998                 *postfix_ptr = new (_pool) PostfixListAST(ast);
       
  3999                 postfix_ptr = &(*postfix_ptr)->next;
       
  4000             } else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) {
       
  4001                 PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST;
       
  4002                 ast->incr_decr_token = consumeToken();
       
  4003                 *postfix_ptr = new (_pool) PostfixListAST(ast);
       
  4004                 postfix_ptr = &(*postfix_ptr)->next;
       
  4005             } else if (LA() == T_DOT || LA() == T_ARROW) {
       
  4006                 MemberAccessAST *ast = new (_pool) MemberAccessAST;
       
  4007                 ast->access_token = consumeToken();
       
  4008                 if (LA() == T_TEMPLATE)
       
  4009                     ast->template_token = consumeToken();
       
  4010                 if (! parseNameId(ast->member_name))
       
  4011                     _translationUnit->error(cursor(), "expected unqualified-id before token `%s'",
       
  4012                                             tok().spell());
       
  4013                 *postfix_ptr = new (_pool) PostfixListAST(ast);
       
  4014                 postfix_ptr = &(*postfix_ptr)->next;
       
  4015             } else break;
       
  4016         } // while
       
  4017 
       
  4018         if (postfix_expressions) {
       
  4019             PostfixExpressionAST *ast = new (_pool) PostfixExpressionAST;
       
  4020             ast->base_expression = node;
       
  4021             ast->postfix_expression_list = postfix_expressions;
       
  4022             node = ast;
       
  4023         }
       
  4024         return true;
       
  4025     }
       
  4026     return false;
       
  4027 }
       
  4028 
       
  4029 bool Parser::parseUnaryExpression(ExpressionAST *&node)
       
  4030 {
       
  4031     DEBUG_THIS_RULE();
       
  4032     switch (LA()) {
       
  4033     case T_PLUS_PLUS:
       
  4034     case T_MINUS_MINUS:
       
  4035     case T_STAR:
       
  4036     case T_AMPER:
       
  4037     case T_PLUS:
       
  4038     case T_MINUS:
       
  4039     case T_EXCLAIM: {
       
  4040         unsigned op = cursor();
       
  4041         UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST;
       
  4042         ast->unary_op_token = consumeToken();
       
  4043         if (! parseCastExpression(ast->expression)) {
       
  4044             _translationUnit->error(op, "expected expression after token `%s'",
       
  4045                                     _translationUnit->spell(op));
       
  4046         }
       
  4047         node = ast;
       
  4048         return true;
       
  4049     }
       
  4050 
       
  4051     case T_TILDE: {
       
  4052         if (LA(2) == T_IDENTIFIER && LA(3) == T_LPAREN)
       
  4053             break; // prefer destructor names
       
  4054 
       
  4055         UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST;
       
  4056         ast->unary_op_token = consumeToken();
       
  4057         parseCastExpression(ast->expression);
       
  4058         node = ast;
       
  4059         return true;
       
  4060     }
       
  4061 
       
  4062     case T_SIZEOF: {
       
  4063         SizeofExpressionAST *ast = new (_pool) SizeofExpressionAST;
       
  4064         ast->sizeof_token = consumeToken();
       
  4065 
       
  4066         if (LA() == T_LPAREN) {
       
  4067             unsigned lparen_token = consumeToken();
       
  4068             if (parseTypeId(ast->expression) && LA() == T_RPAREN) {
       
  4069                 ast->lparen_token = lparen_token;
       
  4070                 ast->rparen_token = consumeToken();
       
  4071                 node = ast;
       
  4072                 return true;
       
  4073             } else {
       
  4074                 rewind(lparen_token);
       
  4075             }
       
  4076         }
       
  4077 
       
  4078         parseUnaryExpression(ast->expression);
       
  4079         node = ast;
       
  4080         return true;
       
  4081     }
       
  4082 
       
  4083     default:
       
  4084         break;
       
  4085     } // switch
       
  4086 
       
  4087     if (LA() == T_NEW || (LA(1) == T_COLON_COLON &&
       
  4088                           LA(2) == T_NEW))
       
  4089         return parseNewExpression(node);
       
  4090     else if (LA() == T_DELETE || (LA(1) == T_COLON_COLON &&
       
  4091                                   LA(2) == T_DELETE))
       
  4092         return parseDeleteExpression(node);
       
  4093     else
       
  4094         return parsePostfixExpression(node);
       
  4095 }
       
  4096 
       
  4097 // new-placement ::= T_LPAREN expression-list T_RPAREN
       
  4098 bool Parser::parseNewPlacement(NewPlacementAST *&node)
       
  4099 {
       
  4100     DEBUG_THIS_RULE();
       
  4101     if (LA() == T_LPAREN) {
       
  4102         unsigned lparen_token = consumeToken();
       
  4103         ExpressionListAST *expression_list = 0;
       
  4104         if (parseExpressionList(expression_list) && expression_list && LA() == T_RPAREN) {
       
  4105             unsigned rparen_token = consumeToken();
       
  4106             NewPlacementAST *ast = new (_pool) NewPlacementAST;
       
  4107             ast->lparen_token = lparen_token;
       
  4108             ast->expression_list = expression_list;
       
  4109             ast->rparen_token = rparen_token;
       
  4110             node = ast;
       
  4111             return true;
       
  4112         }
       
  4113     }
       
  4114 
       
  4115     return false;
       
  4116 }
       
  4117 
       
  4118 // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
       
  4119 //                    new-type-id new-initializer.opt
       
  4120 // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
       
  4121 //                    T_LPAREN type-id T_RPAREN new-initializer.opt
       
  4122 bool Parser::parseNewExpression(ExpressionAST *&node)
       
  4123 {
       
  4124     DEBUG_THIS_RULE();
       
  4125     if (! (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)))
       
  4126         return false;
       
  4127 
       
  4128     NewExpressionAST *ast = new (_pool) NewExpressionAST;
       
  4129     if (LA() == T_COLON_COLON)
       
  4130         ast->scope_token = consumeToken();
       
  4131 
       
  4132     ast->new_token = consumeToken();
       
  4133 
       
  4134     NewPlacementAST *new_placement = 0;
       
  4135 
       
  4136     if (parseNewPlacement(new_placement)) {
       
  4137         unsigned after_new_placement = cursor();
       
  4138 
       
  4139         NewTypeIdAST *new_type_id = 0;
       
  4140         if (parseNewTypeId(new_type_id)) {
       
  4141             ast->new_placement = new_placement;
       
  4142             ast->new_type_id = new_type_id;
       
  4143             parseNewInitializer(ast->new_initializer);
       
  4144             // recognized new-placement.opt new-type-id new-initializer.opt
       
  4145             node = ast;
       
  4146             return true;
       
  4147         }
       
  4148 
       
  4149         rewind(after_new_placement);
       
  4150         if (LA() == T_LPAREN) {
       
  4151             unsigned lparen_token = consumeToken();
       
  4152             ExpressionAST *type_id = 0;
       
  4153             if (parseTypeId(type_id) && LA() == T_RPAREN) {
       
  4154                 ast->new_placement = new_placement;
       
  4155                 ast->lparen_token = lparen_token;
       
  4156                 ast->type_id = type_id;
       
  4157                 ast->rparen_token = consumeToken();
       
  4158                 parseNewInitializer(ast->new_initializer);
       
  4159                 node = ast;
       
  4160                 return true;
       
  4161             }
       
  4162         }
       
  4163     }
       
  4164 
       
  4165     rewind(ast->new_token + 1);
       
  4166 
       
  4167     if (LA() == T_LPAREN) {
       
  4168         unsigned lparen_token = consumeToken();
       
  4169         ExpressionAST *type_id = 0;
       
  4170         if (parseTypeId(type_id) && LA() == T_RPAREN) {
       
  4171             ast->lparen_token = lparen_token;
       
  4172             ast->type_id = type_id;
       
  4173             ast->rparen_token = consumeToken();
       
  4174             parseNewInitializer(ast->new_initializer);
       
  4175             node = ast;
       
  4176             return true;
       
  4177         }
       
  4178     }
       
  4179 
       
  4180     parseNewTypeId(ast->new_type_id);
       
  4181     parseNewInitializer(ast->new_initializer);
       
  4182     node = ast;
       
  4183     return true;
       
  4184 }
       
  4185 
       
  4186 bool Parser::parseNewTypeId(NewTypeIdAST *&node)
       
  4187 {
       
  4188     DEBUG_THIS_RULE();
       
  4189     SpecifierListAST *typeSpec = 0;
       
  4190     if (! parseTypeSpecifier(typeSpec))
       
  4191         return false;
       
  4192 
       
  4193     NewTypeIdAST *ast = new (_pool) NewTypeIdAST;
       
  4194     ast->type_specifier_list = typeSpec;
       
  4195 
       
  4196     PtrOperatorListAST **ptrop_it = &ast->ptr_operator_list;
       
  4197     while (parsePtrOperator(*ptrop_it))
       
  4198         ptrop_it = &(*ptrop_it)->next;
       
  4199 
       
  4200     NewArrayDeclaratorListAST **it = &ast->new_array_declarator_list;
       
  4201     while (parseNewArrayDeclarator(*it))
       
  4202         it = &(*it)->next;
       
  4203 
       
  4204     node = ast;
       
  4205     return true;
       
  4206 }
       
  4207 
       
  4208 
       
  4209 bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node)
       
  4210 {
       
  4211     DEBUG_THIS_RULE();
       
  4212     if (LA() != T_LBRACKET)
       
  4213         return false;
       
  4214 
       
  4215     NewArrayDeclaratorAST *ast = new (_pool) NewArrayDeclaratorAST;
       
  4216     ast->lbracket_token = consumeToken();
       
  4217     parseExpression(ast->expression);
       
  4218     match(T_RBRACKET, &ast->rbracket_token);
       
  4219 
       
  4220     node = new (_pool) NewArrayDeclaratorListAST;
       
  4221     node->value = ast;
       
  4222     return true;
       
  4223 }
       
  4224 
       
  4225 bool Parser::parseNewInitializer(NewInitializerAST *&node)
       
  4226 {
       
  4227     DEBUG_THIS_RULE();
       
  4228     if (LA() == T_LPAREN) {
       
  4229         unsigned lparen_token = consumeToken();
       
  4230         ExpressionAST *expression = 0;
       
  4231         if (LA() == T_RPAREN || parseExpression(expression)) {
       
  4232             NewInitializerAST *ast = new (_pool) NewInitializerAST;
       
  4233             ast->lparen_token = lparen_token;
       
  4234             ast->expression = expression;
       
  4235             match(T_RPAREN, &ast->rparen_token);
       
  4236             node = ast;
       
  4237             return true;
       
  4238         }
       
  4239     }
       
  4240     return false;
       
  4241 }
       
  4242 
       
  4243 bool Parser::parseDeleteExpression(ExpressionAST *&node)
       
  4244 {
       
  4245     DEBUG_THIS_RULE();
       
  4246     if (LA() == T_DELETE || (LA() == T_COLON_COLON && LA(2) == T_DELETE)) {
       
  4247         DeleteExpressionAST *ast = new (_pool) DeleteExpressionAST;
       
  4248 
       
  4249         if (LA() == T_COLON_COLON)
       
  4250             ast->scope_token = consumeToken();
       
  4251 
       
  4252         ast->delete_token = consumeToken();
       
  4253 
       
  4254         if (LA() == T_LBRACKET) {
       
  4255             ast->lbracket_token = consumeToken();
       
  4256             match(T_RBRACKET, &ast->rbracket_token);
       
  4257         }
       
  4258 
       
  4259         parseCastExpression(ast->expression);
       
  4260         node = ast;
       
  4261         return true;
       
  4262     }
       
  4263     return false;
       
  4264 }
       
  4265 
       
  4266 bool Parser::parseCastExpression(ExpressionAST *&node)
       
  4267 {
       
  4268     DEBUG_THIS_RULE();
       
  4269     if (LA() == T_LPAREN) {
       
  4270         unsigned lparen_token = consumeToken();
       
  4271         ExpressionAST *type_id = 0;
       
  4272         if (parseTypeId(type_id) && LA() == T_RPAREN) {
       
  4273             unsigned rparen_token = consumeToken();
       
  4274             ExpressionAST *expression = 0;
       
  4275             if (parseCastExpression(expression)) {
       
  4276                 CastExpressionAST *ast = new (_pool) CastExpressionAST;
       
  4277                 ast->lparen_token = lparen_token;
       
  4278                 ast->type_id = type_id;
       
  4279                 ast->rparen_token = rparen_token;
       
  4280                 ast->expression = expression;
       
  4281                 node = ast;
       
  4282                 return true;
       
  4283             }
       
  4284         }
       
  4285         rewind(lparen_token);
       
  4286     }
       
  4287     return parseUnaryExpression(node);
       
  4288 }
       
  4289 
       
  4290 bool Parser::parsePmExpression(ExpressionAST *&node)
       
  4291 {
       
  4292     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::PointerToMember)
       
  4293 }
       
  4294 
       
  4295 bool Parser::parseMultiplicativeExpression(ExpressionAST *&node)
       
  4296 {
       
  4297     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Multiplicative)
       
  4298 }
       
  4299 
       
  4300 bool Parser::parseAdditiveExpression(ExpressionAST *&node)
       
  4301 {
       
  4302     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Additive)
       
  4303 }
       
  4304 
       
  4305 bool Parser::parseShiftExpression(ExpressionAST *&node)
       
  4306 {
       
  4307     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Shift)
       
  4308 }
       
  4309 
       
  4310 bool Parser::parseRelationalExpression(ExpressionAST *&node)
       
  4311 {
       
  4312     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Relational)
       
  4313 }
       
  4314 
       
  4315 bool Parser::parseEqualityExpression(ExpressionAST *&node)
       
  4316 {
       
  4317     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Equality)
       
  4318 }
       
  4319 
       
  4320 bool Parser::parseAndExpression(ExpressionAST *&node)
       
  4321 {
       
  4322     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::And)
       
  4323 }
       
  4324 
       
  4325 bool Parser::parseExclusiveOrExpression(ExpressionAST *&node)
       
  4326 {
       
  4327     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::ExclusiveOr)
       
  4328 }
       
  4329 
       
  4330 bool Parser::parseInclusiveOrExpression(ExpressionAST *&node)
       
  4331 {
       
  4332     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::InclusiveOr)
       
  4333 }
       
  4334 
       
  4335 bool Parser::parseLogicalAndExpression(ExpressionAST *&node)
       
  4336 {
       
  4337     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::LogicalAnd)
       
  4338 }
       
  4339 
       
  4340 bool Parser::parseLogicalOrExpression(ExpressionAST *&node)
       
  4341 {
       
  4342     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::LogicalOr)
       
  4343 }
       
  4344 
       
  4345 bool Parser::parseConditionalExpression(ExpressionAST *&node)
       
  4346 {
       
  4347     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Conditional)
       
  4348 }
       
  4349 
       
  4350 bool Parser::parseAssignmentExpression(ExpressionAST *&node)
       
  4351 {
       
  4352     DEBUG_THIS_RULE();
       
  4353     if (LA() == T_THROW)
       
  4354         return parseThrowExpression(node);
       
  4355     else
       
  4356         PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Assignment)
       
  4357 }
       
  4358 
       
  4359 bool Parser::parseQtMethod(ExpressionAST *&node)
       
  4360 {
       
  4361     DEBUG_THIS_RULE();
       
  4362     if (LA() == T_SIGNAL || LA() == T_SLOT) {
       
  4363         QtMethodAST *ast = new (_pool) QtMethodAST;
       
  4364         ast->method_token = consumeToken();
       
  4365         match(T_LPAREN, &ast->lparen_token);
       
  4366         if (! parseDeclarator(ast->declarator))
       
  4367             _translationUnit->error(cursor(), "expected a function declarator before token `%s'",
       
  4368                                     tok().spell());
       
  4369         match(T_RPAREN, &ast->rparen_token);
       
  4370         node = ast;
       
  4371         return true;
       
  4372     }
       
  4373     return false;
       
  4374 }
       
  4375 
       
  4376 bool Parser::parseConstantExpression(ExpressionAST *&node)
       
  4377 {
       
  4378     DEBUG_THIS_RULE();
       
  4379     return parseConditionalExpression(node);
       
  4380 }
       
  4381 
       
  4382 bool Parser::parseExpression(ExpressionAST *&node)
       
  4383 {
       
  4384     DEBUG_THIS_RULE();
       
  4385 
       
  4386     if (_expressionDepth > MAX_EXPRESSION_DEPTH)
       
  4387         return false;
       
  4388 
       
  4389     ++_expressionDepth;
       
  4390     bool success = parseCommaExpression(node);
       
  4391     --_expressionDepth;
       
  4392     return success;
       
  4393 }
       
  4394 
       
  4395 void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence)
       
  4396 {
       
  4397     DEBUG_THIS_RULE();
       
  4398 
       
  4399     while (precedence(tok().kind(), _templateArguments) >= minPrecedence) {
       
  4400         const int operPrecedence = precedence(tok().kind(), _templateArguments);
       
  4401         const int oper = consumeToken();
       
  4402 
       
  4403         ConditionalExpressionAST *condExpr = 0;
       
  4404         if (operPrecedence == Prec::Conditional) {
       
  4405             condExpr = new (_pool) ConditionalExpressionAST;
       
  4406             condExpr->question_token = oper;
       
  4407             if (oper == T_COLON) {
       
  4408                 // GNU extension:
       
  4409                 //   logical-or-expression '?' ':' conditional-expression
       
  4410                 condExpr->left_expression = 0;
       
  4411             } else {
       
  4412                 parseExpression(condExpr->left_expression);
       
  4413             }
       
  4414             match(T_COLON, &condExpr->colon_token);
       
  4415         }
       
  4416 
       
  4417         ExpressionAST *rhs = 0;
       
  4418         const bool isCPlusPlus = true;
       
  4419         if (operPrecedence <= Prec::Conditional && isCPlusPlus) {
       
  4420             // in C++ you can put a throw in the right-most expression of a conditional expression,
       
  4421             // or an assignment, so some special handling:
       
  4422             if (!parseAssignmentExpression(rhs))
       
  4423                 return;
       
  4424         } else {
       
  4425             // for C & all other expressions:
       
  4426             if (!parseCastExpression(rhs))
       
  4427                 return;
       
  4428         }
       
  4429 
       
  4430         for (int tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments);
       
  4431                 precedenceAhead > operPrecedence && isBinaryOperator(tokenKindAhead)
       
  4432                         || precedenceAhead == operPrecedence && isRightAssociative(tokenKindAhead);
       
  4433                 tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments)) {
       
  4434             parseExpressionWithOperatorPrecedence(rhs, precedenceAhead);
       
  4435         }
       
  4436 
       
  4437         if (condExpr) { // we were parsing a ternairy conditional expression
       
  4438             condExpr->condition = lhs;
       
  4439             condExpr->right_expression = rhs;
       
  4440             lhs = condExpr;
       
  4441         } else {
       
  4442             BinaryExpressionAST *expr = new (_pool) BinaryExpressionAST;
       
  4443             expr->left_expression = lhs;
       
  4444             expr->binary_op_token = oper;
       
  4445             expr->right_expression = rhs;
       
  4446             lhs = expr;
       
  4447         }
       
  4448     }
       
  4449 }
       
  4450 
       
  4451 bool Parser::parseCommaExpression(ExpressionAST *&node)
       
  4452 {
       
  4453     PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Comma)
       
  4454 }
       
  4455 
       
  4456 bool Parser::parseThrowExpression(ExpressionAST *&node)
       
  4457 {
       
  4458     DEBUG_THIS_RULE();
       
  4459     if (LA() == T_THROW) {
       
  4460         ThrowExpressionAST *ast = new (_pool) ThrowExpressionAST;
       
  4461         ast->throw_token = consumeToken();
       
  4462         parseAssignmentExpression(ast->expression);
       
  4463         node = ast;
       
  4464         return true;
       
  4465     }
       
  4466     return false;
       
  4467 }
       
  4468 
       
  4469 bool Parser::lookAtObjCSelector() const
       
  4470 {
       
  4471     switch (LA()) {
       
  4472     case T_IDENTIFIER:
       
  4473     case T_OR:
       
  4474     case T_AND:
       
  4475     case T_NOT:
       
  4476     case T_XOR:
       
  4477     case T_BITOR:
       
  4478     case T_COMPL:
       
  4479     case T_OR_EQ:
       
  4480     case T_AND_EQ:
       
  4481     case T_BITAND:
       
  4482     case T_NOT_EQ:
       
  4483     case T_XOR_EQ:
       
  4484         return true;
       
  4485 
       
  4486     default:
       
  4487         if (tok().isKeyword())
       
  4488             return true;
       
  4489     } // switch
       
  4490 
       
  4491     return false;
       
  4492 }
       
  4493 
       
  4494 // objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
       
  4495 //
       
  4496 bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
       
  4497 {
       
  4498     DEBUG_THIS_RULE();
       
  4499     if (LA() != T_AT_CLASS)
       
  4500         return false;
       
  4501 
       
  4502     ObjCClassForwardDeclarationAST *ast = new (_pool) ObjCClassForwardDeclarationAST;
       
  4503 
       
  4504     ast->class_token = consumeToken();
       
  4505     unsigned identifier_token = 0;
       
  4506     match(T_IDENTIFIER, &identifier_token);
       
  4507 
       
  4508     ast->identifier_list = new (_pool) ObjCIdentifierListAST;
       
  4509     SimpleNameAST *name = new (_pool) SimpleNameAST;
       
  4510     name->identifier_token = identifier_token;
       
  4511     ast->identifier_list->value = name;
       
  4512     ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
       
  4513 
       
  4514     while (LA() == T_COMMA) {
       
  4515         consumeToken(); // consume T_COMMA
       
  4516         match(T_IDENTIFIER, &identifier_token);
       
  4517 
       
  4518         *nextId = new (_pool) ObjCIdentifierListAST;
       
  4519         name = new (_pool) SimpleNameAST;
       
  4520         name->identifier_token = identifier_token;
       
  4521         (*nextId)->value = name;
       
  4522         nextId = &(*nextId)->next;
       
  4523     }
       
  4524 
       
  4525     match(T_SEMICOLON, &ast->semicolon_token);
       
  4526     node = ast;
       
  4527     return true;
       
  4528 }
       
  4529 
       
  4530 // objc-interface ::= attribute-specifier-list-opt objc-class-interface
       
  4531 // objc-interface ::= objc-category-interface
       
  4532 //
       
  4533 // objc-class-interface ::= T_AT_INTERFACE T_IDENTIFIER (T_COLON T_IDENTIFIER)?
       
  4534 //                          objc-protocol-refs-opt
       
  4535 //                          objc-class-instance-variables-opt
       
  4536 //                          objc-interface-declaration-list
       
  4537 //                          T_AT_END
       
  4538 //
       
  4539 // objc-category-interface ::= T_AT_INTERFACE T_IDENTIFIER
       
  4540 //                             T_LPAREN T_IDENTIFIER? T_RPAREN
       
  4541 //                             objc-protocol-refs-opt
       
  4542 //                             objc-interface-declaration-list
       
  4543 //                             T_AT_END
       
  4544 //
       
  4545 bool Parser::parseObjCInterface(DeclarationAST *&node,
       
  4546                                 SpecifierListAST *attributes)
       
  4547 {
       
  4548     DEBUG_THIS_RULE();
       
  4549     if (! attributes && LA() == T___ATTRIBUTE__) {
       
  4550         SpecifierListAST **attr = &attributes;
       
  4551         while (parseAttributeSpecifier(*attr))
       
  4552             attr = &(*attr)->next;
       
  4553     }
       
  4554 
       
  4555     if (LA() != T_AT_INTERFACE)
       
  4556         return false;
       
  4557 
       
  4558     unsigned objc_interface_token = consumeToken();
       
  4559     unsigned identifier_token = 0;
       
  4560     match(T_IDENTIFIER, &identifier_token);
       
  4561 
       
  4562     if (LA() == T_LPAREN) {
       
  4563         // a category interface
       
  4564 
       
  4565         if (attributes)
       
  4566             _translationUnit->error(attributes->firstToken(),
       
  4567                                     "invalid attributes for category interface declaration");
       
  4568 
       
  4569         ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
       
  4570         ast->attribute_list = attributes;
       
  4571         ast->interface_token = objc_interface_token;
       
  4572         SimpleNameAST *class_name = new (_pool) SimpleNameAST;
       
  4573         class_name->identifier_token= identifier_token;
       
  4574         ast->class_name = class_name;
       
  4575 
       
  4576         match(T_LPAREN, &ast->lparen_token);
       
  4577         if (LA() == T_IDENTIFIER) {
       
  4578             SimpleNameAST *category_name = new (_pool) SimpleNameAST;
       
  4579             category_name->identifier_token = consumeToken();
       
  4580             ast->category_name = category_name;
       
  4581         }
       
  4582 
       
  4583         match(T_RPAREN, &ast->rparen_token);
       
  4584 
       
  4585         parseObjCProtocolRefs(ast->protocol_refs);
       
  4586 
       
  4587         DeclarationListAST **nextMembers = &ast->member_declaration_list;
       
  4588         DeclarationAST *declaration = 0;
       
  4589         while (parseObjCInterfaceMemberDeclaration(declaration)) {
       
  4590             *nextMembers = new (_pool) DeclarationListAST;
       
  4591             (*nextMembers)->value = declaration;
       
  4592             nextMembers = &(*nextMembers)->next;
       
  4593         }
       
  4594 
       
  4595         match(T_AT_END, &ast->end_token);
       
  4596 
       
  4597         node = ast;
       
  4598         return true;
       
  4599     } else {
       
  4600         // a class interface declaration
       
  4601         ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
       
  4602         ast->attribute_list = attributes;
       
  4603         ast->interface_token = objc_interface_token;
       
  4604         SimpleNameAST* class_name = new (_pool) SimpleNameAST;
       
  4605         class_name->identifier_token = identifier_token;
       
  4606         ast->class_name = class_name;
       
  4607 
       
  4608         if (LA() == T_COLON) {
       
  4609             ast->colon_token = consumeToken();
       
  4610             SimpleNameAST *superclass = new (_pool) SimpleNameAST;
       
  4611             match(T_IDENTIFIER, &superclass->identifier_token);
       
  4612             ast->superclass = superclass;
       
  4613         }
       
  4614 
       
  4615         parseObjCProtocolRefs(ast->protocol_refs);
       
  4616         parseObjClassInstanceVariables(ast->inst_vars_decl);
       
  4617 
       
  4618         DeclarationListAST **nextMembers = &ast->member_declaration_list;
       
  4619         DeclarationAST *declaration = 0;
       
  4620         while (parseObjCInterfaceMemberDeclaration(declaration)) {
       
  4621             *nextMembers = new (_pool) DeclarationListAST;
       
  4622             (*nextMembers)->value = declaration;
       
  4623             nextMembers = &(*nextMembers)->next;
       
  4624         }
       
  4625 
       
  4626         match(T_AT_END, &ast->end_token);
       
  4627 
       
  4628         node = ast;
       
  4629         return true;
       
  4630     }
       
  4631 }
       
  4632 
       
  4633 // objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
       
  4634 //
       
  4635 bool Parser::parseObjCProtocol(DeclarationAST *&node,
       
  4636                                SpecifierListAST *attributes)
       
  4637 {
       
  4638     DEBUG_THIS_RULE();
       
  4639     if (! attributes && LA() == T___ATTRIBUTE__) {
       
  4640         SpecifierListAST **attr = &attributes;
       
  4641         while (parseAttributeSpecifier(*attr))
       
  4642             attr = &(*attr)->next;
       
  4643     }
       
  4644 
       
  4645     if (LA() != T_AT_PROTOCOL)
       
  4646         return false;
       
  4647 
       
  4648     unsigned protocol_token = consumeToken();
       
  4649     unsigned identifier_token = 0;
       
  4650     match(T_IDENTIFIER, &identifier_token);
       
  4651 
       
  4652     if (LA() == T_COMMA || LA() == T_SEMICOLON) {
       
  4653         // a protocol forward declaration
       
  4654 
       
  4655         ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
       
  4656         ast->attribute_list = attributes;
       
  4657         ast->protocol_token = protocol_token;
       
  4658         ast->identifier_list = new (_pool) ObjCIdentifierListAST;
       
  4659         SimpleNameAST *name = new (_pool) SimpleNameAST;
       
  4660         name->identifier_token = identifier_token;
       
  4661         ast->identifier_list->value = name;
       
  4662         ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
       
  4663 
       
  4664         while (LA() == T_COMMA) {
       
  4665             consumeToken(); // consume T_COMMA
       
  4666             match(T_IDENTIFIER, &identifier_token);
       
  4667 
       
  4668             *nextId = new (_pool) ObjCIdentifierListAST;
       
  4669             name = new (_pool) SimpleNameAST;
       
  4670             name->identifier_token = identifier_token;
       
  4671             (*nextId)->value = name;
       
  4672             nextId = &(*nextId)->next;
       
  4673         }
       
  4674 
       
  4675         match(T_SEMICOLON, &ast->semicolon_token);
       
  4676         node = ast;
       
  4677         return true;
       
  4678     } else {
       
  4679         // a protocol definition
       
  4680         ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
       
  4681         ast->attribute_list = attributes;
       
  4682         ast->protocol_token = protocol_token;
       
  4683         SimpleNameAST *name = new (_pool) SimpleNameAST;
       
  4684         name->identifier_token = identifier_token;
       
  4685         ast->name = name;
       
  4686 
       
  4687         parseObjCProtocolRefs(ast->protocol_refs);
       
  4688 
       
  4689         DeclarationListAST **nextMembers = &ast->member_declaration_list;
       
  4690         DeclarationAST *declaration = 0;
       
  4691         while (parseObjCInterfaceMemberDeclaration(declaration)) {
       
  4692             *nextMembers = new (_pool) DeclarationListAST;
       
  4693             (*nextMembers)->value = declaration;
       
  4694             nextMembers = &(*nextMembers)->next;
       
  4695         }
       
  4696 
       
  4697         match(T_AT_END, &ast->end_token);
       
  4698 
       
  4699         node = ast;
       
  4700         return true;
       
  4701     }
       
  4702 }
       
  4703 
       
  4704 // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER (T_COLON T_IDENTIFIER)?
       
  4705 //                         objc-class-instance-variables-opt
       
  4706 // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER T_LPAREN T_IDENTIFIER T_RPAREN
       
  4707 //
       
  4708 bool Parser::parseObjCImplementation(DeclarationAST *&node)
       
  4709 {
       
  4710     DEBUG_THIS_RULE();
       
  4711     if (LA() != T_AT_IMPLEMENTATION)
       
  4712         return false;
       
  4713 
       
  4714     unsigned implementation_token = consumeToken();
       
  4715     unsigned identifier_token = 0;
       
  4716     match(T_IDENTIFIER, &identifier_token);
       
  4717 
       
  4718     if (LA() == T_LPAREN) {
       
  4719         // a category implementation
       
  4720         ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
       
  4721         ast->implementation_token = implementation_token;
       
  4722         SimpleNameAST *class_name = new (_pool) SimpleNameAST;
       
  4723         class_name->identifier_token = identifier_token;
       
  4724         ast->class_name = class_name;
       
  4725 
       
  4726         match(T_LPAREN, &ast->lparen_token);
       
  4727         SimpleNameAST *category_name = new (_pool) SimpleNameAST;
       
  4728         match(T_IDENTIFIER, &category_name->identifier_token);
       
  4729         ast->category_name = category_name;
       
  4730         match(T_RPAREN, &ast->rparen_token);
       
  4731 
       
  4732         parseObjCMethodDefinitionList(ast->member_declaration_list);
       
  4733         match(T_AT_END, &ast->end_token);
       
  4734 
       
  4735         node = ast;
       
  4736     } else {
       
  4737         // a class implementation
       
  4738         ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
       
  4739         ast->implementation_token = implementation_token;
       
  4740         SimpleNameAST *class_name = new (_pool) SimpleNameAST;
       
  4741         class_name->identifier_token = identifier_token;
       
  4742         ast->class_name = class_name;
       
  4743 
       
  4744         if (LA() == T_COLON) {
       
  4745             ast->colon_token = consumeToken();
       
  4746             SimpleNameAST *superclass = new (_pool) SimpleNameAST;
       
  4747             match(T_IDENTIFIER, &superclass->identifier_token);
       
  4748             ast->superclass = superclass;
       
  4749         }
       
  4750 
       
  4751         parseObjClassInstanceVariables(ast->inst_vars_decl);
       
  4752         parseObjCMethodDefinitionList(ast->member_declaration_list);
       
  4753         match(T_AT_END, &ast->end_token);
       
  4754 
       
  4755         node = ast;
       
  4756     }
       
  4757 
       
  4758     return true;
       
  4759 }
       
  4760 
       
  4761 bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
       
  4762 {
       
  4763     DEBUG_THIS_RULE();
       
  4764     DeclarationListAST **next = &node;
       
  4765 
       
  4766     while (LA() && LA() != T_AT_END) {
       
  4767         unsigned start = cursor();
       
  4768         DeclarationAST *declaration = 0;
       
  4769 
       
  4770         switch (LA()) {
       
  4771         case T_PLUS:
       
  4772         case T_MINUS:
       
  4773             parseObjCMethodDefinition(declaration);
       
  4774 
       
  4775             if (start == cursor())
       
  4776                 consumeToken();
       
  4777             break;
       
  4778 
       
  4779         case T_SEMICOLON:
       
  4780             consumeToken();
       
  4781             break;
       
  4782 
       
  4783         case T_AT_SYNTHESIZE: {
       
  4784             ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
       
  4785             ast->synthesized_token = consumeToken();
       
  4786             ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
       
  4787             ast->property_identifier_list = last;
       
  4788             last->value = new (_pool) ObjCSynthesizedPropertyAST;
       
  4789             match(T_IDENTIFIER, &last->value->property_identifier_token);
       
  4790 
       
  4791             if (LA() == T_EQUAL) {
       
  4792                 last->value->equals_token = consumeToken();
       
  4793 
       
  4794                 match(T_IDENTIFIER, &last->value->alias_identifier_token);
       
  4795             }
       
  4796 
       
  4797             while (LA() == T_COMMA) {
       
  4798                 consumeToken(); // consume T_COMMA
       
  4799 
       
  4800                 last->next = new (_pool) ObjCSynthesizedPropertyListAST;
       
  4801                 last = last->next;
       
  4802 
       
  4803                 last->value = new (_pool) ObjCSynthesizedPropertyAST;
       
  4804                 match(T_IDENTIFIER, &last->value->property_identifier_token);
       
  4805 
       
  4806                 if (LA() == T_EQUAL) {
       
  4807                     last->value->equals_token = consumeToken();
       
  4808 
       
  4809                     match(T_IDENTIFIER, &last->value->alias_identifier_token);
       
  4810                 }
       
  4811             }
       
  4812 
       
  4813             match(T_SEMICOLON, &ast->semicolon_token);
       
  4814 
       
  4815             declaration = ast;
       
  4816             break;
       
  4817         }
       
  4818 
       
  4819         case T_AT_DYNAMIC: {
       
  4820             ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
       
  4821             ast->dynamic_token = consumeToken();
       
  4822             ast->property_identifier_list = new (_pool) ObjCIdentifierListAST;
       
  4823             SimpleNameAST *name = new (_pool) SimpleNameAST;
       
  4824             match(T_IDENTIFIER, &name->identifier_token);
       
  4825             ast->property_identifier_list->value = name;
       
  4826 
       
  4827             ObjCIdentifierListAST *last = ast->property_identifier_list;
       
  4828             while (LA() == T_COMMA) {
       
  4829                 consumeToken(); // consume T_COMMA
       
  4830 
       
  4831                 last->next = new (_pool) ObjCIdentifierListAST;
       
  4832                 last = last->next;
       
  4833                 name = new (_pool) SimpleNameAST;
       
  4834                 match(T_IDENTIFIER, &name->identifier_token);
       
  4835                 last->value = name;
       
  4836             }
       
  4837 
       
  4838             match(T_SEMICOLON, &ast->semicolon_token);
       
  4839 
       
  4840             declaration = ast;
       
  4841             break;
       
  4842         }
       
  4843 
       
  4844         default:
       
  4845             if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
       
  4846                 parseDeclaration(declaration);
       
  4847             } else {
       
  4848                 if (! parseBlockDeclaration(declaration)) {
       
  4849                     rewind(start);
       
  4850                     _translationUnit->error(cursor(),
       
  4851                                             "skip token `%s'", tok().spell());
       
  4852 
       
  4853                     consumeToken();
       
  4854                 }
       
  4855             }
       
  4856             break;
       
  4857         } // switch
       
  4858 
       
  4859         if (declaration) {
       
  4860             *next = new (_pool) DeclarationListAST;
       
  4861             (*next)->value = declaration;
       
  4862             next = &(*next)->next;
       
  4863         }
       
  4864     }
       
  4865 
       
  4866     return true;
       
  4867 }
       
  4868 
       
  4869 bool Parser::parseObjCMethodDefinition(DeclarationAST *&node)
       
  4870 {
       
  4871     DEBUG_THIS_RULE();
       
  4872     ObjCMethodPrototypeAST *method_prototype = 0;
       
  4873     if (! parseObjCMethodPrototype(method_prototype))
       
  4874         return false;
       
  4875 
       
  4876     ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
       
  4877     ast->method_prototype = method_prototype;
       
  4878 
       
  4879     // Objective-C allows you to write:
       
  4880     // - (void) foo; { body; }
       
  4881     // so a method is a forward declaration when it doesn't have a _body_.
       
  4882     // However, we still need to read the semicolon.
       
  4883     if (LA() == T_SEMICOLON) {
       
  4884         ast->semicolon_token = consumeToken();
       
  4885     }
       
  4886 
       
  4887     parseFunctionBody(ast->function_body);
       
  4888 
       
  4889     node = ast;
       
  4890     return true;
       
  4891 }
       
  4892 
       
  4893 // objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
       
  4894 //
       
  4895 bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
       
  4896 {
       
  4897     DEBUG_THIS_RULE();
       
  4898     if (LA() != T_LESS)
       
  4899         return false;
       
  4900 
       
  4901     ObjCProtocolRefsAST *ast = new (_pool) ObjCProtocolRefsAST;
       
  4902 
       
  4903     match(T_LESS, &ast->less_token);
       
  4904 
       
  4905     unsigned identifier_token = 0;
       
  4906     match(T_IDENTIFIER, &identifier_token);
       
  4907     ast->identifier_list = new (_pool) ObjCIdentifierListAST;
       
  4908     SimpleNameAST *name = new (_pool) SimpleNameAST;
       
  4909     name->identifier_token = identifier_token;
       
  4910     ast->identifier_list->value = name;
       
  4911     ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
       
  4912 
       
  4913     while (LA() == T_COMMA) {
       
  4914         consumeToken(); // consume T_COMMA
       
  4915         match(T_IDENTIFIER, &identifier_token);
       
  4916 
       
  4917         *nextId = new (_pool) ObjCIdentifierListAST;
       
  4918         name = new (_pool) SimpleNameAST;
       
  4919         name->identifier_token = identifier_token;
       
  4920         (*nextId)->value = name;
       
  4921         nextId = &(*nextId)->next;
       
  4922     }
       
  4923 
       
  4924     match(T_GREATER, &ast->greater_token);
       
  4925     node = ast;
       
  4926     return true;
       
  4927 }
       
  4928 
       
  4929 // objc-class-instance-variables ::= T_LBRACE
       
  4930 //                                   objc-instance-variable-decl-list-opt
       
  4931 //                                   T_RBRACE
       
  4932 //
       
  4933 bool Parser::parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST *&node)
       
  4934 {
       
  4935     DEBUG_THIS_RULE();
       
  4936     if (LA() != T_LBRACE)
       
  4937         return false;
       
  4938 
       
  4939     ObjCInstanceVariablesDeclarationAST *ast = new (_pool) ObjCInstanceVariablesDeclarationAST;
       
  4940     match(T_LBRACE, &ast->lbrace_token);
       
  4941 
       
  4942     for (DeclarationListAST **next = &ast->instance_variable_list; LA(); next = &(*next)->next) {
       
  4943         if (LA() == T_RBRACE)
       
  4944             break;
       
  4945 
       
  4946         const unsigned start = cursor();
       
  4947 
       
  4948         *next = new (_pool) DeclarationListAST;
       
  4949         parseObjCInstanceVariableDeclaration((*next)->value);
       
  4950 
       
  4951         if (start == cursor()) {
       
  4952             // skip stray token.
       
  4953             _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
       
  4954             consumeToken();
       
  4955         }
       
  4956     }
       
  4957 
       
  4958     match(T_RBRACE, &ast->rbrace_token);
       
  4959 
       
  4960     node = ast;
       
  4961     return true;
       
  4962 }
       
  4963 
       
  4964 // objc-interface-declaration ::= T_AT_REQUIRED
       
  4965 // objc-interface-declaration ::= T_AT_OPTIONAL
       
  4966 // objc-interface-declaration ::= T_SEMICOLON
       
  4967 // objc-interface-declaration ::= objc-property-declaration
       
  4968 // objc-interface-declaration ::= objc-method-prototype
       
  4969 bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
       
  4970 {
       
  4971     DEBUG_THIS_RULE();
       
  4972     switch (LA()) {
       
  4973     case T_AT_END:
       
  4974         return false;
       
  4975 
       
  4976     case T_AT_REQUIRED:
       
  4977     case T_AT_OPTIONAL:
       
  4978         consumeToken();
       
  4979         return true;
       
  4980 
       
  4981     case T_SEMICOLON:
       
  4982         consumeToken();
       
  4983         return true;
       
  4984 
       
  4985     case T_AT_PROPERTY: {
       
  4986         return parseObjCPropertyDeclaration(node);
       
  4987     }
       
  4988 
       
  4989     case T_PLUS:
       
  4990     case T_MINUS: {
       
  4991         ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
       
  4992         if (parseObjCMethodPrototype(ast->method_prototype)) {
       
  4993             match(T_SEMICOLON, &ast->semicolon_token);
       
  4994             node = ast;
       
  4995             return true;
       
  4996         } else {
       
  4997             return false;
       
  4998         }
       
  4999     }
       
  5000 
       
  5001     case T_ENUM:
       
  5002     case T_CLASS:
       
  5003     case T_STRUCT:
       
  5004     case T_UNION: {
       
  5005         return parseSimpleDeclaration(node, /*accept struct declarators */ true);
       
  5006     }
       
  5007 
       
  5008     default: {
       
  5009         return parseSimpleDeclaration(node, /*accept struct declarators */ true);
       
  5010     } // default
       
  5011 
       
  5012     } // switch
       
  5013 }
       
  5014 
       
  5015 // objc-instance-variable-declaration ::= objc-visibility-specifier
       
  5016 // objc-instance-variable-declaration ::= block-declaration
       
  5017 //
       
  5018 bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
       
  5019 {
       
  5020     DEBUG_THIS_RULE();
       
  5021     switch (LA()) {
       
  5022         case T_AT_PRIVATE:
       
  5023         case T_AT_PROTECTED:
       
  5024         case T_AT_PUBLIC:
       
  5025         case T_AT_PACKAGE: {
       
  5026             ObjCVisibilityDeclarationAST *ast = new (_pool) ObjCVisibilityDeclarationAST;
       
  5027             ast->visibility_token = consumeToken();
       
  5028             node = ast;
       
  5029             return true;
       
  5030         }
       
  5031 
       
  5032         default:
       
  5033             return parseSimpleDeclaration(node, true);
       
  5034     }
       
  5035 }
       
  5036 
       
  5037 // objc-property-declaration ::=
       
  5038 //    T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration
       
  5039 //
       
  5040 bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes)
       
  5041 {
       
  5042     DEBUG_THIS_RULE();
       
  5043     if (LA() != T_AT_PROPERTY)
       
  5044         return false;
       
  5045 
       
  5046     ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST;
       
  5047     ast->attribute_list = attributes;
       
  5048     ast->property_token = consumeToken();
       
  5049 
       
  5050     if (LA() == T_LPAREN) {
       
  5051         match(T_LPAREN, &ast->lparen_token);
       
  5052 
       
  5053         ObjCPropertyAttributeAST *property_attribute = 0;
       
  5054         if (parseObjCPropertyAttribute(property_attribute)) {
       
  5055             ast->property_attribute_list = new (_pool) ObjCPropertyAttributeListAST;
       
  5056             ast->property_attribute_list->value = property_attribute;
       
  5057             ObjCPropertyAttributeListAST *last = ast->property_attribute_list;
       
  5058 
       
  5059             while (LA() == T_COMMA) {
       
  5060                 consumeToken(); // consume T_COMMA
       
  5061                 last->next = new (_pool) ObjCPropertyAttributeListAST;
       
  5062                 last = last->next;
       
  5063                 if (!parseObjCPropertyAttribute(last->value)) {
       
  5064                     _translationUnit->error(_tokenIndex, "expected token `%s' got `%s'",
       
  5065                                             Token::name(T_IDENTIFIER), tok().spell());
       
  5066                     break;
       
  5067                 }
       
  5068             }
       
  5069         }
       
  5070 
       
  5071         match(T_RPAREN, &ast->rparen_token);
       
  5072     }
       
  5073 
       
  5074     if (parseSimpleDeclaration(ast->simple_declaration, /*accept-struct-declarators = */ true))
       
  5075         node = ast;
       
  5076     else
       
  5077         _translationUnit->error(_tokenIndex, "expected a simple declaration");
       
  5078 
       
  5079     return true;
       
  5080 }
       
  5081 
       
  5082 // objc-method-prototype ::= (T_PLUS | T_MINUS) objc-method-decl objc-method-attrs-opt
       
  5083 //
       
  5084 // objc-method-decl ::= objc-type-name? objc-selector
       
  5085 // objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt
       
  5086 //
       
  5087 bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
       
  5088 {
       
  5089     DEBUG_THIS_RULE();
       
  5090     if (LA() != T_PLUS && LA() != T_MINUS)
       
  5091         return false;
       
  5092 
       
  5093     ObjCMethodPrototypeAST *ast = new (_pool) ObjCMethodPrototypeAST;
       
  5094     ast->method_type_token = consumeToken();
       
  5095 
       
  5096     parseObjCTypeName(ast->type_name);
       
  5097 
       
  5098     if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) {
       
  5099         ObjCSelectorArgumentAST *argument = 0;
       
  5100         ObjCMessageArgumentDeclarationAST *declaration = 0;
       
  5101         parseObjCKeywordDeclaration(argument, declaration);
       
  5102 
       
  5103         ObjCSelectorWithArgumentsAST *sel = new (_pool) ObjCSelectorWithArgumentsAST;
       
  5104         ast->selector = sel;
       
  5105         ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST;
       
  5106         sel->selector_argument_list = lastSel;
       
  5107         sel->selector_argument_list->value = argument;
       
  5108 
       
  5109         ast->argument_list = new (_pool) ObjCMessageArgumentDeclarationListAST;
       
  5110         ast->argument_list->value = declaration;
       
  5111         ObjCMessageArgumentDeclarationListAST *lastArg = ast->argument_list;
       
  5112 
       
  5113         while (parseObjCKeywordDeclaration(argument, declaration)) {
       
  5114             lastSel->next = new (_pool) ObjCSelectorArgumentListAST;
       
  5115             lastSel = lastSel->next;
       
  5116             lastSel->value = argument;
       
  5117 
       
  5118             lastArg->next = new (_pool) ObjCMessageArgumentDeclarationListAST;
       
  5119             lastArg = lastArg->next;
       
  5120             lastArg->value = declaration;
       
  5121         }
       
  5122 
       
  5123         while (LA() == T_COMMA) {
       
  5124             consumeToken();
       
  5125 
       
  5126             if (LA() == T_DOT_DOT_DOT) {
       
  5127                 ast->dot_dot_dot_token = consumeToken();
       
  5128                 break;
       
  5129             }
       
  5130 
       
  5131             // TODO: Is this still valid, and if so, should it be stored in the AST? (EV)
       
  5132             DeclarationAST *parameter_declaration = 0;
       
  5133             parseParameterDeclaration(parameter_declaration);
       
  5134         }
       
  5135     } else if (lookAtObjCSelector()) {
       
  5136         ObjCSelectorWithoutArgumentsAST *sel = new (_pool) ObjCSelectorWithoutArgumentsAST;
       
  5137         parseObjCSelector(sel->name_token);
       
  5138         ast->selector = sel;
       
  5139     } else {
       
  5140         _translationUnit->error(cursor(), "expected a selector");
       
  5141     }
       
  5142 
       
  5143     SpecifierListAST **attr = &ast->attribute_list;
       
  5144     while (parseAttributeSpecifier(*attr))
       
  5145         attr = &(*attr)->next;
       
  5146 
       
  5147     node = ast;
       
  5148     return true;
       
  5149 }
       
  5150 
       
  5151 // objc-property-attribute ::= getter '=' identifier
       
  5152 // objc-property-attribute ::= setter '=' identifier ':'
       
  5153 // objc-property-attribute ::= readonly
       
  5154 // objc-property-attribute ::= readwrite
       
  5155 // objc-property-attribute ::= assign
       
  5156 // objc-property-attribute ::= retain
       
  5157 // objc-property-attribute ::= copy
       
  5158 // objc-property-attribute ::= nonatomic
       
  5159 bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node)
       
  5160 {
       
  5161     DEBUG_THIS_RULE();
       
  5162     if (LA() != T_IDENTIFIER)
       
  5163         return false;
       
  5164 
       
  5165     node = new (_pool) ObjCPropertyAttributeAST;
       
  5166 
       
  5167     const Identifier *id = tok().identifier;
       
  5168     const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
       
  5169     switch (k) {
       
  5170     case Token_copy:
       
  5171     case Token_assign:
       
  5172     case Token_retain:
       
  5173     case Token_readonly:
       
  5174     case Token_readwrite:
       
  5175     case Token_nonatomic:
       
  5176         node->attribute_identifier_token = consumeToken();
       
  5177         return true;
       
  5178 
       
  5179     case Token_getter: {
       
  5180         node->attribute_identifier_token = consumeToken();
       
  5181         match(T_EQUAL, &node->equals_token);
       
  5182         ObjCSelectorWithoutArgumentsAST *selector = new (_pool) ObjCSelectorWithoutArgumentsAST;
       
  5183         match(T_IDENTIFIER, &selector->name_token);
       
  5184         node->method_selector = selector;
       
  5185         return true;
       
  5186     }
       
  5187 
       
  5188     case Token_setter: {
       
  5189         node->attribute_identifier_token = consumeToken();
       
  5190         match(T_EQUAL, &node->equals_token);
       
  5191         ObjCSelectorWithArgumentsAST *selector = new (_pool) ObjCSelectorWithArgumentsAST;
       
  5192         selector->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
       
  5193         selector->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
       
  5194         match(T_IDENTIFIER, &selector->selector_argument_list->value->name_token);
       
  5195         match(T_COLON, &selector->selector_argument_list->value->colon_token);
       
  5196         node->method_selector = selector;
       
  5197         return true;
       
  5198     }
       
  5199 
       
  5200     default:
       
  5201         return false;
       
  5202     }
       
  5203 }
       
  5204 
       
  5205 // objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
       
  5206 //
       
  5207 bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
       
  5208 {
       
  5209     DEBUG_THIS_RULE();
       
  5210     if (LA() != T_LPAREN)
       
  5211         return false;
       
  5212 
       
  5213     ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST;
       
  5214     match(T_LPAREN, &ast->lparen_token);
       
  5215     parseObjCTypeQualifiers(ast->type_qualifier_token);
       
  5216     parseTypeId(ast->type_id);
       
  5217     match(T_RPAREN, &ast->rparen_token);
       
  5218     node = ast;
       
  5219     return true;
       
  5220 }
       
  5221 
       
  5222 // objc-selector ::= T_IDENTIFIER | keyword
       
  5223 //
       
  5224 bool Parser::parseObjCSelector(unsigned &selector_token)
       
  5225 {
       
  5226     DEBUG_THIS_RULE();
       
  5227     if (! lookAtObjCSelector())
       
  5228         return false;
       
  5229 
       
  5230     selector_token = consumeToken();
       
  5231     return true;
       
  5232 }
       
  5233 
       
  5234 // objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER
       
  5235 //
       
  5236 bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, ObjCMessageArgumentDeclarationAST *&node)
       
  5237 {
       
  5238     DEBUG_THIS_RULE();
       
  5239     if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON)))
       
  5240         return false;
       
  5241 
       
  5242     node = new (_pool) ObjCMessageArgumentDeclarationAST;
       
  5243     argument = new (_pool) ObjCSelectorArgumentAST;
       
  5244 
       
  5245     parseObjCSelector(argument->name_token);
       
  5246     match(T_COLON, &argument->colon_token);
       
  5247 
       
  5248     parseObjCTypeName(node->type_name);
       
  5249 
       
  5250     SpecifierListAST **attr = &node->attribute_list;
       
  5251     while (parseAttributeSpecifier(*attr))
       
  5252         attr = &(*attr)->next;
       
  5253 
       
  5254     match(T_IDENTIFIER, &node->param_name_token);
       
  5255 
       
  5256     return true;
       
  5257 }
       
  5258 
       
  5259 bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
       
  5260 {
       
  5261     DEBUG_THIS_RULE();
       
  5262     if (LA() != T_IDENTIFIER)
       
  5263         return false;
       
  5264 
       
  5265     const Identifier *id = tok().identifier;
       
  5266     const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
       
  5267     if (k == Token_identifier)
       
  5268         return false;
       
  5269     type_qualifier = consumeToken();
       
  5270     return true;
       
  5271 }
       
  5272 
       
  5273 bool Parser::peekAtObjCContextKeyword(int kind)
       
  5274 {
       
  5275     if (LA() != T_IDENTIFIER)
       
  5276         return false;
       
  5277 
       
  5278     const Identifier *id = tok().identifier;
       
  5279     const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
       
  5280     return k == kind;
       
  5281 }
       
  5282 
       
  5283 bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
       
  5284 {
       
  5285     DEBUG_THIS_RULE();
       
  5286 
       
  5287     if (peekAtObjCContextKeyword(kind)) {
       
  5288         in_token = consumeToken();
       
  5289         return true;
       
  5290     } else {
       
  5291         return false;
       
  5292     }
       
  5293 }
       
  5294 
       
  5295