1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
32 // Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
34 // Permission is hereby granted, free of charge, to any person obtaining a copy
35 // of this software and associated documentation files (the "Software"), to deal
36 // in the Software without restriction, including without limitation the rights
37 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
38 // copies of the Software, and to permit persons to whom the Software is
39 // furnished to do so, subject to the following conditions:
41 // The above copyright notice and this permission notice shall be included in
42 // all copies or substantial portions of the Software.
44 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58 #include "ObjectiveCTypeQualifiers.h"
59 #include "QtContextKeywords.h"
61 #include <cstdio> // for putchar
64 # define va_copy(dst, src) ((dst) = (src))
65 #elif defined(__INTEL_COMPILER) && !defined(va_copy)
66 # define va_copy __va_copy
69 #define CPLUSPLUS_NO_DEBUG_RULE
70 #define MAX_EXPRESSION_DEPTH 100
72 using namespace CPlusPlus;
81 DebugRule(const char *name, const char *spell, unsigned idx, bool blocked)
84 for (int i = 0; i <= depth; ++i)
88 fprintf(stderr, " %s, ahead: '%s' (%d) - block-errors: %d\n", name, spell, idx, blocked);
95 int DebugRule::depth = 0;
97 inline bool lookAtAssignmentOperator(int tokenKind)
104 case T_GREATER_GREATER_EQUAL:
105 case T_LESS_LESS_EQUAL:
107 case T_PERCENT_EQUAL:
136 } // namespace Precedece
138 inline int precedence(int tokenKind, bool templateArguments)
140 // ### this will/might need some tuning for C++0x
141 // (see: [temp.names]p3)
142 if (templateArguments && tokenKind == T_GREATER)
145 if (lookAtAssignmentOperator(tokenKind))
146 return Prec::Assignment;
149 case T_COMMA: return Prec::Comma;
150 case T_QUESTION: return Prec::Conditional;
151 case T_PIPE_PIPE: return Prec::LogicalOr;
152 case T_AMPER_AMPER: return Prec::LogicalAnd;
153 case T_PIPE: return Prec::InclusiveOr;
154 case T_CARET: return Prec::ExclusiveOr;
155 case T_AMPER: return Prec::And;
157 case T_EXCLAIM_EQUAL: return Prec::Equality;
161 case T_GREATER_EQUAL: return Prec::Relational;
163 case T_GREATER_GREATER: return Prec::ExclusiveOr;
165 case T_MINUS: return Prec::Additive;
168 case T_PERCENT: return Prec::Multiplicative;
170 case T_DOT_STAR: return Prec::PointerToMember;
171 default: return Prec::Unknown;
175 inline bool isBinaryOperator(int tokenKind)
176 { return precedence(tokenKind, false) != Prec::Unknown; }
178 inline bool isRightAssociative(int tokenKind)
180 const int prec = precedence(tokenKind, false);
181 return prec == Prec::Conditional || prec == Prec::Assignment;
184 } // end of anonymous namespace
186 #ifndef CPLUSPLUS_NO_DEBUG_RULE
187 # define DEBUG_THIS_RULE() DebugRule __debug_rule__(__func__, tok().spell(), cursor(), _translationUnit->blockErrors())
189 # define DEBUG_THIS_RULE() do {} while (0)
192 #define PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, minPrecedence) { \
193 if (LA() == T_THROW) { \
194 if (!parseThrowExpression(node)) \
196 } else if (!parseCastExpression(node)) \
199 parseExpressionWithOperatorPrecedence(node, minPrecedence); \
203 Parser::Parser(TranslationUnit *unit)
204 : _translationUnit(unit),
205 _control(_translationUnit->control()),
206 _pool(_translationUnit->memoryPool()),
208 _templateArguments(0),
209 _qtMocRunEnabled(false),
210 _cxx0xEnabled(false),
212 _inFunctionBody(false),
213 _inObjCImplementationContext(false),
214 _inExpressionStatement(false),
221 bool Parser::qtMocRunEnabled() const
222 { return _qtMocRunEnabled; }
224 void Parser::setQtMocRunEnabled(bool onoff)
225 { _qtMocRunEnabled = onoff; }
227 bool Parser::cxx0xEnabled() const
228 { return _cxx0xEnabled; }
230 void Parser::setCxxOxEnabled(bool onoff)
231 { _cxx0xEnabled = onoff; }
233 bool Parser::objCEnabled() const
234 { return _objCEnabled; }
236 void Parser::setObjCEnabled(bool onoff)
237 { _objCEnabled = onoff; }
239 bool Parser::switchTemplateArguments(bool templateArguments)
241 bool previousTemplateArguments = _templateArguments;
242 _templateArguments = templateArguments;
243 return previousTemplateArguments;
246 bool Parser::blockErrors(bool block)
247 { return _translationUnit->blockErrors(block); }
249 bool Parser::skipUntil(int token)
251 while (int tk = LA()) {
261 void Parser::skipUntilDeclaration()
263 for (; ; consumeToken()) {
279 // member specification
288 case T_Q_PRIVATE_PROPERTY:
293 // Qt function specifiers
306 case T_AT_IMPLEMENTATION:
311 if (lookAtBuiltinTypeSpecifier() || lookAtClassKey() ||
312 lookAtFunctionSpecifier() || lookAtStorageClassSpecifier())
318 bool Parser::skipUntilStatement()
320 while (int tk = LA()) {
362 case T_AT_SYNCHRONIZED:
374 bool Parser::skip(int l, int r)
378 while (int tk = LA()) {
383 else if (l != T_LBRACE && (tk == T_LBRACE ||
397 void Parser::match(int kind, unsigned *token)
400 *token = consumeToken();
403 error(_tokenIndex, "expected token `%s' got `%s'",
404 Token::name(kind), tok().spell());
408 bool Parser::parseClassOrNamespaceName(NameAST *&node)
411 if (LA() == T_IDENTIFIER && (LA(2) == T_COLON_COLON || LA(2) == T_LESS)) {
412 unsigned identifier_token = cursor();
414 if (LA(2) == T_LESS && parseTemplateId(node) && LA() == T_COLON_COLON)
417 rewind(identifier_token);
419 if (LA(2) == T_COLON_COLON) {
420 SimpleNameAST *ast = new (_pool) SimpleNameAST;
421 ast->identifier_token = consumeToken();
425 } else if (LA() == T_TEMPLATE) {
426 unsigned template_token = consumeToken();
427 if (parseTemplateId(node, template_token) && LA() == T_COLON_COLON)
429 rewind(template_token);
434 bool Parser::parseTemplateId(NameAST *&node, unsigned template_token)
438 const unsigned start = cursor();
440 if (LA() == T_IDENTIFIER && LA(2) == T_LESS) {
441 TemplateIdAST *ast = new (_pool) TemplateIdAST;
442 ast->template_token = template_token;
443 ast->identifier_token = consumeToken();
444 ast->less_token = consumeToken();
445 if (LA() == T_GREATER || parseTemplateArgumentList(
446 ast->template_argument_list)) {
447 if (LA() == T_GREATER) {
448 ast->greater_token = consumeToken();
460 bool Parser::parseNestedNameSpecifier(NestedNameSpecifierListAST *&node,
461 bool /*acceptTemplateId*/)
464 NestedNameSpecifierListAST **nested_name_specifier = &node;
465 NameAST *class_or_namespace_name = 0;
466 if (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
467 unsigned scope_token = consumeToken();
469 NestedNameSpecifierAST *name = new (_pool) NestedNameSpecifierAST;
470 name->class_or_namespace_name = class_or_namespace_name;
471 name->scope_token = scope_token;
473 *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
474 nested_name_specifier = &(*nested_name_specifier)->next;
476 while (parseClassOrNamespaceName(class_or_namespace_name) && LA() == T_COLON_COLON) {
477 scope_token = consumeToken();
479 name = new (_pool) NestedNameSpecifierAST;
480 name->class_or_namespace_name = class_or_namespace_name;
481 name->scope_token = scope_token;
483 *nested_name_specifier = new (_pool) NestedNameSpecifierListAST(name);
484 nested_name_specifier = &(*nested_name_specifier)->next;
496 bool Parser::parseNestedNameSpecifierOpt(NestedNameSpecifierListAST *&name, bool acceptTemplateId)
499 unsigned start = cursor();
500 if (! parseNestedNameSpecifier(name, acceptTemplateId))
505 bool Parser::parseName(NameAST *&node, bool acceptTemplateId)
508 unsigned global_scope_token = 0;
513 case T_TILDE: // destructor-name-id
514 case T_OPERATOR: // operator-name-id
515 case T_TEMPLATE: // template introduced template-id
521 if (LA() == T_COLON_COLON)
522 global_scope_token = consumeToken();
524 NestedNameSpecifierListAST *nested_name_specifier = 0;
525 parseNestedNameSpecifierOpt(nested_name_specifier,
526 /*acceptTemplateId=*/ true);
528 NameAST *unqualified_name = 0;
529 if (parseUnqualifiedName(unqualified_name,
530 /*acceptTemplateId=*/ acceptTemplateId || nested_name_specifier != 0)) {
531 if (! global_scope_token && ! nested_name_specifier) {
532 node = unqualified_name;
536 QualifiedNameAST *ast = new (_pool) QualifiedNameAST;
537 ast->global_scope_token = global_scope_token;
538 ast->nested_name_specifier_list = nested_name_specifier;
539 ast->unqualified_name = unqualified_name;
547 bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
550 TranslationUnitAST *ast = new (_pool) TranslationUnitAST;
551 DeclarationListAST **decl = &ast->declaration_list;
554 unsigned start_declaration = cursor();
556 DeclarationAST *declaration = 0;
558 if (parseDeclaration(declaration)) {
559 *decl = new (_pool) DeclarationListAST;
560 (*decl)->value = declaration;
561 decl = &(*decl)->next;
563 error(start_declaration, "expected a declaration");
564 rewind(start_declaration + 1);
565 skipUntilDeclaration();
569 if (TopLevelDeclarationProcessor *processor = _control->topLevelDeclarationProcessor()) {
570 if (processor->processDeclaration(declaration))
574 _templateArgumentList.clear();
581 bool Parser::parseEmptyDeclaration(DeclarationAST *&node)
584 if (LA() == T_SEMICOLON) {
585 EmptyDeclarationAST *ast = new (_pool) EmptyDeclarationAST;
586 ast->semicolon_token = consumeToken();
593 bool Parser::parseDeclaration(DeclarationAST *&node)
598 return parseEmptyDeclaration(node);
601 return parseNamespace(node);
604 return parseUsing(node);
607 return parseAsmDefinition(node);
611 return parseTemplateDeclaration(node);
615 return parseObjCClassForwardDeclaration(node);
618 return parseObjCInterface(node);
621 return parseObjCProtocol(node);
623 case T_AT_IMPLEMENTATION:
624 return parseObjCImplementation(node);
626 case T_Q_DECLARE_INTERFACE:
629 unsigned lparen_token = 0;
630 match(T_LPAREN, &lparen_token);
633 unsigned comma_token = 0;
634 match(T_COMMA, &comma_token);
635 unsigned string_literal = 0;
636 match(T_STRING_LITERAL, &string_literal);
637 unsigned rparen_token = 0;
638 match(T_RPAREN, &rparen_token);
642 // TODO: should this be done here, or higher-up?
643 error(cursor(), "skip stray token `%s'", tok().spell());
648 if (_objCEnabled && LA() == T___ATTRIBUTE__) {
649 const unsigned start = cursor();
650 SpecifierListAST *attributes = 0, **attr = &attributes;
651 while (parseAttributeSpecifier(*attr))
652 attr = &(*attr)->next;
653 if (LA() == T_AT_INTERFACE)
654 return parseObjCInterface(node, attributes);
655 else if (LA() == T_AT_PROTOCOL)
656 return parseObjCProtocol(node, attributes);
657 else if (LA() == T_AT_PROPERTY)
658 return parseObjCPropertyDeclaration(node, attributes);
662 if (LA() == T_EXTERN && LA(2) == T_TEMPLATE)
663 return parseTemplateDeclaration(node);
664 else if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL)
665 return parseLinkageSpecification(node);
667 return parseSimpleDeclaration(node);
675 bool Parser::parseLinkageSpecification(DeclarationAST *&node)
678 if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
679 LinkageSpecificationAST *ast = new (_pool) LinkageSpecificationAST;
680 ast->extern_token = consumeToken();
681 ast->extern_type_token = consumeToken();
683 if (LA() == T_LBRACE)
684 parseLinkageBody(ast->declaration);
686 parseDeclaration(ast->declaration);
695 bool Parser::parseLinkageBody(DeclarationAST *&node)
698 if (LA() == T_LBRACE) {
699 LinkageBodyAST *ast = new (_pool) LinkageBodyAST;
700 ast->lbrace_token = consumeToken();
701 DeclarationListAST **declaration_ptr = &ast->declaration_list;
703 while (int tk = LA()) {
707 unsigned start_declaration = cursor();
708 DeclarationAST *declaration = 0;
709 if (parseDeclaration(declaration)) {
710 *declaration_ptr = new (_pool) DeclarationListAST;
711 (*declaration_ptr)->value = declaration;
712 declaration_ptr = &(*declaration_ptr)->next;
714 error(start_declaration, "expected a declaration");
715 rewind(start_declaration + 1);
716 skipUntilDeclaration();
719 _templateArgumentList.clear();
721 match(T_RBRACE, &ast->rbrace_token);
728 // ### rename parseNamespaceAliarOrDeclaration?
729 bool Parser::parseNamespace(DeclarationAST *&node)
732 if (LA() != T_NAMESPACE)
735 unsigned namespace_token = consumeToken();
737 if (LA() == T_IDENTIFIER && LA(2) == T_EQUAL) {
738 NamespaceAliasDefinitionAST *ast =
739 new (_pool) NamespaceAliasDefinitionAST;
740 ast->namespace_token = namespace_token;
741 ast->namespace_name_token = consumeToken();
742 ast->equal_token = consumeToken();
743 parseName(ast->name);
744 match(T_SEMICOLON, &ast->semicolon_token);
749 NamespaceAST *ast = new (_pool) NamespaceAST;
750 ast->namespace_token = namespace_token;
751 if (LA() == T_IDENTIFIER)
752 ast->identifier_token = consumeToken();
753 SpecifierListAST **attr_ptr = &ast->attribute_list;
754 while (LA() == T___ATTRIBUTE__) {
755 parseAttributeSpecifier(*attr_ptr);
756 attr_ptr = &(*attr_ptr)->next;
758 if (LA() == T_LBRACE)
759 parseLinkageBody(ast->linkage_body);
764 bool Parser::parseUsing(DeclarationAST *&node)
770 if (LA(2) == T_NAMESPACE)
771 return parseUsingDirective(node);
773 UsingAST *ast = new (_pool) UsingAST;
774 ast->using_token = consumeToken();
776 if (LA() == T_TYPENAME)
777 ast->typename_token = consumeToken();
779 parseName(ast->name);
780 match(T_SEMICOLON, &ast->semicolon_token);
785 bool Parser::parseUsingDirective(DeclarationAST *&node)
788 if (LA() == T_USING && LA(2) == T_NAMESPACE) {
789 UsingDirectiveAST *ast = new (_pool) UsingDirectiveAST;
790 ast->using_token = consumeToken();
791 ast->namespace_token = consumeToken();
792 if (! parseName(ast->name))
793 warning(cursor(), "expected `namespace name' before `%s'",
795 match(T_SEMICOLON, &ast->semicolon_token);
802 bool Parser::parseConversionFunctionId(NameAST *&node)
805 if (LA() != T_OPERATOR)
807 unsigned operator_token = consumeToken();
808 SpecifierListAST *type_specifier = 0;
809 if (! parseTypeSpecifier(type_specifier)) {
812 PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
813 while (parsePtrOperator(*ptr_operators_tail))
814 ptr_operators_tail = &(*ptr_operators_tail)->next;
816 ConversionFunctionIdAST *ast = new (_pool) ConversionFunctionIdAST;
817 ast->operator_token = operator_token;
818 ast->type_specifier_list = type_specifier;
819 ast->ptr_operator_list = ptr_operators;
824 bool Parser::parseOperatorFunctionId(NameAST *&node)
827 if (LA() != T_OPERATOR)
829 unsigned operator_token = consumeToken();
832 if (! parseOperator(op))
835 OperatorFunctionIdAST *ast = new (_pool) OperatorFunctionIdAST;
836 ast->operator_token = operator_token;
842 Parser::TemplateArgumentListEntry *Parser::templateArgumentListEntry(unsigned tokenIndex)
844 std::map<unsigned, TemplateArgumentListEntry>::iterator it =_templateArgumentList.find(tokenIndex);
845 if (it != _templateArgumentList.end())
851 bool Parser::parseTemplateArgumentList(ExpressionListAST *&node)
855 if (TemplateArgumentListEntry *entry = templateArgumentListEntry(cursor())) {
856 rewind(entry->cursor);
858 return entry->ast != 0;
861 unsigned start = cursor();
863 ExpressionListAST **template_argument_ptr = &node;
864 ExpressionAST *template_argument = 0;
865 if (parseTemplateArgument(template_argument)) {
866 *template_argument_ptr = new (_pool) ExpressionListAST;
867 (*template_argument_ptr)->value = template_argument;
868 template_argument_ptr = &(*template_argument_ptr)->next;
870 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
871 consumeToken(); // ### store this token in the AST
873 while (LA() == T_COMMA) {
874 consumeToken(); // consume T_COMMA
876 if (parseTemplateArgument(template_argument)) {
877 *template_argument_ptr = new (_pool) ExpressionListAST;
878 (*template_argument_ptr)->value = template_argument;
879 template_argument_ptr = &(*template_argument_ptr)->next;
881 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
882 consumeToken(); // ### store this token in the AST
886 if (_pool != _translationUnit->memoryPool()) {
887 MemoryPool *pool = _translationUnit->memoryPool();
888 ExpressionListAST *template_argument_list = node;
889 for (ExpressionListAST *iter = template_argument_list, **ast_iter = &node;
890 iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
891 *ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
894 _templateArgumentList.insert(std::make_pair(start, TemplateArgumentListEntry(start, cursor(), node)));
898 _templateArgumentList.insert(std::make_pair(start, TemplateArgumentListEntry(start, cursor(), 0)));
902 bool Parser::parseAsmDefinition(DeclarationAST *&node)
908 AsmDefinitionAST *ast = new (_pool) AsmDefinitionAST;
909 ast->asm_token = consumeToken();
911 if (LA() == T_VOLATILE)
912 ast->volatile_token = consumeToken();
914 match(T_LPAREN, &ast->lparen_token);
915 unsigned string_literal_token = 0;
916 match(T_STRING_LITERAL, &string_literal_token);
917 while (LA() == T_STRING_LITERAL) {
920 if (LA() == T_COLON) {
921 consumeToken(); // skip T_COLON
922 parseAsmOperandList();
923 if (LA() == T_COLON) {
925 parseAsmOperandList();
926 if (LA() == T_COLON) {
928 parseAsmClobberList();
930 } else if (LA() == T_COLON_COLON) {
932 parseAsmClobberList();
934 } else if (LA() == T_COLON_COLON) {
936 parseAsmOperandList();
938 if (LA() == T_COLON) {
940 parseAsmClobberList();
943 match(T_RPAREN, &ast->rparen_token);
944 match(T_SEMICOLON, &ast->semicolon_token);
949 bool Parser::parseAsmOperandList()
952 if (LA() != T_STRING_LITERAL)
955 if (parseAsmOperand()) {
956 while (LA() == T_COMMA) {
966 bool Parser::parseAsmOperand()
969 unsigned string_literal_token = 0;
970 match(T_STRING_LITERAL, &string_literal_token);
972 if (LA() == T_LBRACKET) {
973 /*unsigned lbracket_token = */ consumeToken();
974 match(T_STRING_LITERAL, &string_literal_token);
975 unsigned rbracket_token = 0;
976 match(T_RBRACKET, &rbracket_token);
979 unsigned lparen_token = 0, rparen_token = 0;
980 match(T_LPAREN, &lparen_token);
981 ExpressionAST *expression = 0;
982 parseExpression(expression);
983 match(T_RPAREN, &rparen_token);
987 bool Parser::parseAsmClobberList()
990 if (LA() != T_STRING_LITERAL)
993 unsigned string_literal_token = consumeToken();
995 while (LA() == T_COMMA) {
997 match(T_STRING_LITERAL, &string_literal_token);
1003 bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
1006 if (! (LA(1) == T_TEMPLATE || ((LA(1) == T_EXPORT || LA(1) == T_EXTERN)
1007 && LA(2) == T_TEMPLATE)))
1010 TemplateDeclarationAST *ast = new (_pool) TemplateDeclarationAST;
1012 if (LA() == T_EXPORT || LA() == T_EXPORT)
1013 ast->export_token = consumeToken();
1015 ast->template_token = consumeToken();
1017 if (LA() == T_LESS) {
1018 ast->less_token = consumeToken();
1019 if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list))
1020 match(T_GREATER, &ast->greater_token);
1024 unsigned start_declaration = cursor();
1026 ast->declaration = 0;
1027 if (parseDeclaration(ast->declaration))
1030 error(start_declaration, "expected a declaration");
1031 rewind(start_declaration + 1);
1032 skipUntilDeclaration();
1039 bool Parser::parseOperator(OperatorAST *&node) // ### FIXME
1042 OperatorAST *ast = new (_pool) OperatorAST;
1047 ast->op_token = consumeToken();
1048 if (LA() == T_LBRACKET) {
1049 ast->open_token = consumeToken();
1050 match(T_RBRACKET, &ast->close_token);
1072 case T_EXCLAIM_EQUAL:
1073 case T_GREATER_EQUAL:
1074 case T_GREATER_GREATER_EQUAL:
1076 case T_LESS_LESS_EQUAL:
1078 case T_PERCENT_EQUAL:
1084 case T_GREATER_GREATER:
1092 ast->op_token = consumeToken();
1096 if (LA() == T_LPAREN && LA(2) == T_RPAREN) {
1097 ast->op_token = ast->open_token = consumeToken();
1098 ast->close_token = consumeToken();
1099 } else if (LA() == T_LBRACKET && LA(2) == T_RBRACKET) {
1100 ast->op_token = ast->open_token = consumeToken();
1101 ast->close_token = consumeToken();
1111 bool Parser::parseCvQualifiers(SpecifierListAST *&node)
1115 unsigned start = cursor();
1117 SpecifierListAST **ast = &node;
1119 ast = &(*ast)->next;
1121 while (int tk = LA()) {
1122 if (tk == T_CONST || tk == T_VOLATILE) {
1123 SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
1124 spec->specifier_token = consumeToken();
1125 *ast = new (_pool) SpecifierListAST(spec);
1126 ast = &(*ast)->next;
1127 } else if(LA() == T___ATTRIBUTE__) {
1128 parseAttributeSpecifier(*ast);
1129 ast = &(*ast)->next;
1135 return start != cursor();
1138 bool Parser::parsePtrOperator(PtrOperatorListAST *&node)
1141 if (LA() == T_AMPER || (_cxx0xEnabled && LA() == T_AMPER_AMPER)) {
1142 ReferenceAST *ast = new (_pool) ReferenceAST;
1143 ast->reference_token = consumeToken();
1144 node = new (_pool) PtrOperatorListAST(ast);
1146 } else if (LA() == T_STAR) {
1147 PointerAST *ast = new (_pool) PointerAST;
1148 ast->star_token = consumeToken();
1149 parseCvQualifiers(ast->cv_qualifier_list);
1150 node = new (_pool) PtrOperatorListAST(ast);
1152 } else if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER) {
1153 unsigned scope_or_identifier_token = cursor();
1155 unsigned global_scope_token = 0;
1156 if (LA() == T_COLON_COLON)
1157 global_scope_token = consumeToken();
1159 NestedNameSpecifierListAST *nested_name_specifiers = 0;
1160 bool has_nested_name_specifier = parseNestedNameSpecifier(nested_name_specifiers, true);
1161 if (has_nested_name_specifier && LA() == T_STAR) {
1162 PointerToMemberAST *ast = new (_pool) PointerToMemberAST;
1163 ast->global_scope_token = global_scope_token;
1164 ast->nested_name_specifier_list = nested_name_specifiers;
1165 ast->star_token = consumeToken();
1166 parseCvQualifiers(ast->cv_qualifier_list);
1167 node = new (_pool) PtrOperatorListAST(ast);
1170 rewind(scope_or_identifier_token);
1175 bool Parser::parseTemplateArgument(ExpressionAST *&node)
1178 unsigned start = cursor();
1179 if (parseTypeId(node)) {
1182 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
1185 if (LA(index) == T_COMMA || LA(index) == T_GREATER)
1190 bool previousTemplateArguments = switchTemplateArguments(true);
1191 bool parsed = parseConstantExpression(node);
1192 (void) switchTemplateArguments(previousTemplateArguments);
1196 bool Parser::parseDeclSpecifierSeq(SpecifierListAST *&decl_specifier_seq,
1197 bool onlyTypeSpecifiers,
1201 bool has_type_specifier = false;
1202 NameAST *named_type_specifier = 0;
1203 SpecifierListAST **decl_specifier_seq_ptr = &decl_specifier_seq;
1205 if (lookAtCVQualifier()) {
1206 SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
1207 spec->specifier_token = consumeToken();
1208 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
1209 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
1210 } else if (! onlyTypeSpecifiers && lookAtStorageClassSpecifier()) {
1211 SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
1212 spec->specifier_token = consumeToken();
1213 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
1214 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
1215 } else if (! named_type_specifier && lookAtBuiltinTypeSpecifier()) {
1216 parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr);
1217 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
1218 has_type_specifier = true;
1219 } else if (! has_type_specifier && (LA() == T_COLON_COLON ||
1220 LA() == T_IDENTIFIER)) {
1221 if (! parseName(named_type_specifier))
1223 NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST;
1224 spec->name = named_type_specifier;
1225 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
1226 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
1227 has_type_specifier = true;
1228 } else if (! simplified && ! has_type_specifier && (LA() == T_TYPENAME ||
1230 lookAtClassKey())) {
1231 unsigned startOfElaboratedTypeSpecifier = cursor();
1232 if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
1233 error(startOfElaboratedTypeSpecifier,
1234 "expected an elaborated type specifier");
1237 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
1238 has_type_specifier = true;
1243 return decl_specifier_seq != 0;
1246 bool Parser::parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list)
1249 unsigned start = cursor();
1250 bool blocked = blockErrors(true);
1251 if (parseDeclarator(node, decl_specifier_list)) {
1252 blockErrors(blocked);
1255 blockErrors(blocked);
1257 return parseAbstractDeclarator(node, decl_specifier_list);
1260 bool Parser::parseCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *)
1263 unsigned start = cursor();
1264 SpecifierListAST *attributes = 0;
1265 SpecifierListAST **attribute_ptr = &attributes;
1266 while (LA() == T___ATTRIBUTE__) {
1267 parseAttributeSpecifier(*attribute_ptr);
1268 attribute_ptr = &(*attribute_ptr)->next;
1271 PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
1272 while (parsePtrOperator(*ptr_operators_tail))
1273 ptr_operators_tail = &(*ptr_operators_tail)->next;
1275 if (LA() == T_COLON_COLON || LA() == T_IDENTIFIER || LA() == T_TILDE || LA() == T_OPERATOR
1276 || (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COLON_COLON || LA(2) == T_IDENTIFIER))) {
1278 unsigned dot_dot_dot_token = 0;
1280 if (LA() == T_DOT_DOT_DOT)
1281 dot_dot_dot_token = consumeToken();
1284 if (parseName(name)) {
1285 DeclaratorIdAST *declarator_id = new (_pool) DeclaratorIdAST;
1286 declarator_id->dot_dot_dot_token = dot_dot_dot_token;
1287 declarator_id->name = name;
1288 DeclaratorAST *ast = new (_pool) DeclaratorAST;
1289 ast->attribute_list = attributes;
1290 ast->ptr_operator_list = ptr_operators;
1291 ast->core_declarator = declarator_id;
1295 } else if (decl_specifier_list && LA() == T_LPAREN) {
1297 warning(attributes->firstToken(), "unexpected attribtues");
1299 unsigned lparen_token = consumeToken();
1300 DeclaratorAST *declarator = 0;
1301 if (parseDeclarator(declarator, decl_specifier_list) && LA() == T_RPAREN) {
1302 NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
1303 nested_declarator->lparen_token = lparen_token;
1304 nested_declarator->declarator = declarator;
1305 nested_declarator->rparen_token = consumeToken();
1306 DeclaratorAST *ast = new (_pool) DeclaratorAST;
1307 ast->ptr_operator_list = ptr_operators;
1308 ast->core_declarator = nested_declarator;
1317 static bool maybeCppInitializer(DeclaratorAST *declarator)
1319 if (declarator->ptr_operator_list)
1321 CoreDeclaratorAST *core_declarator = declarator->core_declarator;
1322 if (! core_declarator)
1324 DeclaratorIdAST *declarator_id = core_declarator->asDeclaratorId();
1325 if (! declarator_id)
1327 else if (! declarator_id->name)
1329 else if (! declarator_id->name->asSimpleName())
1335 bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list, ClassSpecifierAST *declaringClass)
1338 if (! parseCoreDeclarator(node, decl_specifier_list, declaringClass))
1341 PostfixDeclaratorListAST **postfix_ptr = &node->postfix_declarator_list;
1344 unsigned startOfPostDeclarator = cursor();
1346 if (LA() == T_LPAREN) {
1347 if (! declaringClass && LA(2) != T_RPAREN && maybeCppInitializer(node)) {
1348 unsigned lparen_token = cursor();
1349 ExpressionAST *initializer = 0;
1351 bool blocked = blockErrors(true);
1352 if (parseInitializer(initializer, &node->equal_token)) {
1353 NestedExpressionAST *expr = 0;
1355 expr = initializer->asNestedExpression();
1357 if (expr->expression && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) {
1358 rewind(lparen_token);
1360 // check for ambiguous declarators.
1363 ParameterDeclarationClauseAST *parameter_declaration_clause = 0;
1364 if (parseParameterDeclarationClause(parameter_declaration_clause) && LA() == T_RPAREN) {
1365 unsigned rparen_token = consumeToken();
1367 FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
1368 ast->lparen_token = lparen_token;
1369 ast->parameter_declaration_clause = parameter_declaration_clause;
1370 ast->as_cpp_initializer = initializer;
1371 ast->rparen_token = rparen_token;
1372 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
1373 postfix_ptr = &(*postfix_ptr)->next;
1375 blockErrors(blocked);
1380 blockErrors(blocked);
1381 rewind(lparen_token);
1387 blockErrors(blocked);
1388 rewind(lparen_token);
1391 FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
1392 ast->lparen_token = consumeToken();
1393 parseParameterDeclarationClause(ast->parameter_declaration_clause);
1394 if (LA() != T_RPAREN) {
1395 rewind(startOfPostDeclarator);
1399 ast->rparen_token = consumeToken();
1400 // ### parse attributes
1401 parseCvQualifiers(ast->cv_qualifier_list);
1402 // ### parse ref-qualifiers
1403 parseExceptionSpecification(ast->exception_specification);
1405 if (_cxx0xEnabled && ! node->ptr_operator_list && LA() == T_ARROW) {
1406 // only allow if there is 1 type spec, which has to be 'auto'
1407 bool hasAuto = false;
1408 for (SpecifierListAST *iter = decl_specifier_list; !hasAuto && iter; iter = iter->next) {
1409 SpecifierAST *spec = iter->value;
1410 if (SimpleSpecifierAST *simpleSpec = spec->asSimpleSpecifier()) {
1411 if (_translationUnit->tokenKind(simpleSpec->specifier_token) == T_AUTO) {
1418 parseTrailingReturnType(ast->trailing_return_type);
1421 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
1422 postfix_ptr = &(*postfix_ptr)->next;
1423 } else if (LA() == T_LBRACKET) {
1424 ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST;
1425 ast->lbracket_token = consumeToken();
1426 if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) {
1427 match(T_RBRACKET, &ast->rbracket_token);
1429 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
1430 postfix_ptr = &(*postfix_ptr)->next;
1435 if (LA() == T___ASM__ && LA(2) == T_LPAREN) { // ### store the asm specifier in the AST
1436 consumeToken(); // skip __asm__
1437 consumeToken(); // skip T_LPAREN
1439 if (skipUntil(T_RPAREN))
1440 consumeToken(); // skip T_RPAREN
1443 SpecifierListAST **spec_ptr = &node->post_attribute_list;
1444 while (LA() == T___ATTRIBUTE__) {
1445 parseAttributeSpecifier(*spec_ptr);
1446 spec_ptr = &(*spec_ptr)->next;
1452 bool Parser::parseAbstractCoreDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list)
1456 PtrOperatorListAST *ptr_operators = 0, **ptr_operators_tail = &ptr_operators;
1457 while (parsePtrOperator(*ptr_operators_tail))
1458 ptr_operators_tail = &(*ptr_operators_tail)->next;
1460 unsigned after_ptr_operators = cursor();
1462 if (LA() == T_LPAREN && LA(2) != T_RPAREN) {
1463 unsigned lparen_token = consumeToken();
1464 DeclaratorAST *declarator = 0;
1465 if (parseAbstractDeclarator(declarator, decl_specifier_list) && LA() == T_RPAREN) {
1466 NestedDeclaratorAST *nested_declarator = new (_pool) NestedDeclaratorAST;
1467 nested_declarator->lparen_token = lparen_token;
1468 nested_declarator->declarator = declarator;
1469 nested_declarator->rparen_token = consumeToken();
1470 DeclaratorAST *ast = new (_pool) DeclaratorAST;
1471 ast->ptr_operator_list = ptr_operators;
1472 ast->core_declarator = nested_declarator;
1478 rewind(after_ptr_operators);
1479 if (ptr_operators) {
1480 DeclaratorAST *ast = new (_pool) DeclaratorAST;
1481 ast->ptr_operator_list = ptr_operators;
1488 bool Parser::parseAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list)
1491 if (! parseAbstractCoreDeclarator(node, decl_specifier_list))
1494 PostfixDeclaratorListAST *postfix_declarators = 0,
1495 **postfix_ptr = &postfix_declarators;
1498 if (LA() == T_LPAREN) {
1499 FunctionDeclaratorAST *ast = new (_pool) FunctionDeclaratorAST;
1500 ast->lparen_token = consumeToken();
1501 if (LA() == T_RPAREN || parseParameterDeclarationClause(ast->parameter_declaration_clause)) {
1502 if (LA() == T_RPAREN)
1503 ast->rparen_token = consumeToken();
1505 parseCvQualifiers(ast->cv_qualifier_list);
1506 parseExceptionSpecification(ast->exception_specification);
1507 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
1508 postfix_ptr = &(*postfix_ptr)->next;
1509 } else if (LA() == T_LBRACKET) {
1510 ArrayDeclaratorAST *ast = new (_pool) ArrayDeclaratorAST;
1511 ast->lbracket_token = consumeToken();
1512 if (LA() == T_RBRACKET || parseConstantExpression(ast->expression)) {
1513 if (LA() == T_RBRACKET)
1514 ast->rbracket_token = consumeToken();
1516 *postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
1517 postfix_ptr = &(*postfix_ptr)->next;
1522 if (postfix_declarators) {
1524 node = new (_pool) DeclaratorAST;
1526 node->postfix_declarator_list = postfix_declarators;
1532 bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
1535 if (LA() == T_ENUM) {
1536 unsigned enum_token = consumeToken();
1539 if (LA() == T_LBRACE) {
1540 EnumSpecifierAST *ast = new (_pool) EnumSpecifierAST;
1541 ast->enum_token = enum_token;
1543 ast->lbrace_token = consumeToken();
1544 unsigned comma_token = 0;
1545 EnumeratorListAST **enumerator_ptr = &ast->enumerator_list;
1546 while (int tk = LA()) {
1550 if (LA() != T_IDENTIFIER) {
1551 error(cursor(), "expected identifier before '%s'", tok().spell());
1552 skipUntil(T_IDENTIFIER);
1555 if (parseEnumerator(*enumerator_ptr)) {
1556 enumerator_ptr = &(*enumerator_ptr)->next;
1559 if (LA() == T_COMMA && LA(2) == T_RBRACE)
1560 ast->stray_comma_token = consumeToken();
1562 if (LA() != T_RBRACE)
1563 match(T_COMMA, &comma_token);
1565 match(T_RBRACE, &ast->rbrace_token);
1566 node = new (_pool) SpecifierListAST(ast);
1573 bool Parser::parseTemplateParameterList(DeclarationListAST *&node)
1576 DeclarationListAST **template_parameter_ptr = &node;
1577 DeclarationAST *declaration = 0;
1578 if (parseTemplateParameter(declaration)) {
1579 *template_parameter_ptr = new (_pool) DeclarationListAST;
1580 (*template_parameter_ptr)->value = declaration;
1581 template_parameter_ptr = &(*template_parameter_ptr)->next;
1583 while (LA() == T_COMMA) {
1584 consumeToken(); // XXX Store this token somewhere
1587 if (parseTemplateParameter(declaration)) {
1588 *template_parameter_ptr = new (_pool) DeclarationListAST;
1589 (*template_parameter_ptr)->value = declaration;
1590 template_parameter_ptr = &(*template_parameter_ptr)->next;
1598 bool Parser::parseTemplateParameter(DeclarationAST *&node)
1601 if (parseTypeParameter(node))
1603 bool previousTemplateArguments = switchTemplateArguments(true);
1604 ParameterDeclarationAST *ast = 0;
1605 bool parsed = parseParameterDeclaration(ast);
1607 (void) switchTemplateArguments(previousTemplateArguments);
1611 bool Parser::parseTypenameTypeParameter(DeclarationAST *&node)
1614 if (LA() == T_CLASS || LA() == T_TYPENAME) {
1615 TypenameTypeParameterAST *ast = new (_pool) TypenameTypeParameterAST;
1616 ast->classkey_token = consumeToken();
1617 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
1618 ast->dot_dot_dot_token = consumeToken();
1619 parseName(ast->name);
1620 if (LA() == T_EQUAL) {
1621 ast->equal_token = consumeToken();
1622 parseTypeId(ast->type_id);
1630 bool Parser::parseTemplateTypeParameter(DeclarationAST *&node)
1633 if (LA() == T_TEMPLATE) {
1634 TemplateTypeParameterAST *ast = new (_pool) TemplateTypeParameterAST;
1635 ast->template_token = consumeToken();
1637 ast->less_token = consumeToken();
1638 parseTemplateParameterList(ast->template_parameter_list);
1639 if (LA() == T_GREATER)
1640 ast->greater_token = consumeToken();
1641 if (LA() == T_CLASS)
1642 ast->class_token = consumeToken();
1643 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
1644 ast->dot_dot_dot_token = consumeToken();
1646 // parse optional name
1647 parseName(ast->name);
1649 if (LA() == T_EQUAL) {
1650 ast->equal_token = consumeToken();
1651 parseTypeId(ast->type_id);
1659 bool Parser::lookAtTypeParameter() const
1661 if (LA() == T_CLASS || LA() == T_TYPENAME) {
1662 if (LA(2) == T_IDENTIFIER) {
1672 } else if (LA(2) == T_COLON_COLON) {
1673 // found something like template <typename ::foo::bar>...
1677 // recognized an anonymous template type parameter. e.g
1678 // template <typename>
1686 bool Parser::parseTypeParameter(DeclarationAST *&node)
1690 if (lookAtTypeParameter())
1691 return parseTypenameTypeParameter(node);
1692 else if (LA() == T_TEMPLATE)
1693 return parseTemplateTypeParameter(node);
1698 bool Parser::parseTypeId(ExpressionAST *&node)
1701 SpecifierListAST *type_specifier = 0;
1702 if (parseTypeSpecifier(type_specifier)) {
1703 TypeIdAST *ast = new (_pool) TypeIdAST;
1704 ast->type_specifier_list = type_specifier;
1705 parseAbstractDeclarator(ast->declarator, type_specifier);
1712 bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node)
1715 if (LA() == T_RPAREN)
1716 return true; // nothing to do
1718 ParameterDeclarationListAST *parameter_declarations = 0;
1720 unsigned dot_dot_dot_token = 0;
1721 if (LA() == T_DOT_DOT_DOT)
1722 dot_dot_dot_token = consumeToken();
1724 parseParameterDeclarationList(parameter_declarations);
1726 if (LA() == T_DOT_DOT_DOT) {
1727 dot_dot_dot_token = consumeToken();
1728 } else if (LA() == T_COMMA && LA(2) == T_DOT_DOT_DOT) {
1729 consumeToken(); // skip comma
1730 dot_dot_dot_token = consumeToken();
1734 if (parameter_declarations || dot_dot_dot_token) {
1735 ParameterDeclarationClauseAST *ast = new (_pool) ParameterDeclarationClauseAST;
1736 ast->parameter_declaration_list = parameter_declarations;
1737 ast->dot_dot_dot_token = dot_dot_dot_token;
1744 bool Parser::parseParameterDeclarationList(ParameterDeclarationListAST *&node)
1747 if (LA() == T_DOT_DOT_DOT || (LA() == T_COMMA && LA(2) == T_DOT_DOT_DOT))
1748 return false; // nothing to do.
1750 ParameterDeclarationListAST **parameter_declaration_ptr = &node;
1751 ParameterDeclarationAST *declaration = 0;
1752 if (parseParameterDeclaration(declaration)) {
1753 *parameter_declaration_ptr = new (_pool) ParameterDeclarationListAST;
1754 (*parameter_declaration_ptr)->value = declaration;
1755 parameter_declaration_ptr = &(*parameter_declaration_ptr)->next;
1756 while (LA() == T_COMMA) {
1759 if (LA() == T_DOT_DOT_DOT)
1763 if (parseParameterDeclaration(declaration)) {
1764 *parameter_declaration_ptr = new (_pool) ParameterDeclarationListAST;
1765 (*parameter_declaration_ptr)->value = declaration;
1766 parameter_declaration_ptr = &(*parameter_declaration_ptr)->next;
1774 bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node)
1777 SpecifierListAST *decl_specifier_seq = 0;
1778 if (parseDeclSpecifierSeq(decl_specifier_seq)) {
1779 ParameterDeclarationAST *ast = new (_pool) ParameterDeclarationAST;
1780 ast->type_specifier_list = decl_specifier_seq;
1781 parseDeclaratorOrAbstractDeclarator(ast->declarator, decl_specifier_seq);
1782 if (LA() == T_EQUAL) {
1783 ast->equal_token = consumeToken();
1784 parseLogicalOrExpression(ast->expression);
1793 const Identifier *Parser::className(ClassSpecifierAST *ast) const
1798 return identifier(ast->name);
1801 const Identifier *Parser::identifier(NameAST *name) const
1806 if (QualifiedNameAST *q = name->asQualifiedName())
1807 name = q->unqualified_name;
1810 if (SimpleNameAST *simple = name->asSimpleName())
1811 return _translationUnit->identifier(simple->identifier_token);
1812 else if (TemplateIdAST *template_id = name->asTemplateId())
1813 return _translationUnit->identifier(template_id->identifier_token);
1819 bool Parser::parseClassSpecifier(SpecifierListAST *&node)
1822 if (! lookAtClassKey())
1825 unsigned classkey_token = consumeToken();
1827 SpecifierListAST *attributes = 0, **attr_ptr = &attributes;
1828 while (LA() == T___ATTRIBUTE__) {
1829 parseAttributeSpecifier(*attr_ptr);
1830 attr_ptr = &(*attr_ptr)->next;
1833 if (LA(1) == T_IDENTIFIER && LA(2) == T_IDENTIFIER) {
1834 warning(cursor(), "skip identifier `%s'",
1842 bool parsed = false;
1844 const bool previousInFunctionBody = _inFunctionBody;
1845 _inFunctionBody = false;
1847 unsigned colon_token = 0;
1848 unsigned dot_dot_dot_token = 0;
1850 if (LA() == T_COLON || LA() == T_LBRACE) {
1851 BaseSpecifierListAST *base_clause_list = 0;
1853 if (LA() == T_COLON) {
1854 colon_token = cursor();
1856 parseBaseClause(base_clause_list);
1858 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
1859 dot_dot_dot_token = consumeToken();
1861 if (LA() != T_LBRACE) {
1862 error(cursor(), "expected `{' before `%s'", tok().spell());
1864 const unsigned saved = cursor();
1866 for (int n = 0; n < 3 && LA() != T_EOF_SYMBOL; ++n, consumeToken()) {
1867 if (LA() == T_LBRACE)
1871 if (LA() != T_LBRACE)
1876 ClassSpecifierAST *ast = new (_pool) ClassSpecifierAST;
1877 ast->classkey_token = classkey_token;
1878 ast->attribute_list = attributes;
1880 ast->colon_token = colon_token;
1881 ast->base_clause_list = base_clause_list;
1882 ast->dot_dot_dot_token = dot_dot_dot_token;
1884 if (LA() == T_LBRACE)
1885 ast->lbrace_token = consumeToken();
1887 DeclarationListAST **declaration_ptr = &ast->member_specifier_list;
1888 while (int tk = LA()) {
1889 if (tk == T_RBRACE) {
1890 ast->rbrace_token = consumeToken();
1894 unsigned start_declaration = cursor();
1895 DeclarationAST *declaration = 0;
1896 if (parseMemberSpecification(declaration, ast)) {
1897 if (declaration) { // paranoia check
1898 *declaration_ptr = new (_pool) DeclarationListAST;
1899 (*declaration_ptr)->value = declaration;
1900 declaration_ptr = &(*declaration_ptr)->next;
1903 if (cursor() == start_declaration) { // more paranoia
1904 rewind(start_declaration + 1);
1905 skipUntilDeclaration();
1908 error(start_declaration, "expected a declaration");
1909 rewind(start_declaration + 1);
1910 skipUntilDeclaration();
1913 node = new (_pool) SpecifierListAST(ast);
1917 _inFunctionBody = previousInFunctionBody;
1922 bool Parser::parseAccessSpecifier(SpecifierAST *&node)
1929 SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST;
1930 ast->specifier_token = consumeToken();
1940 bool Parser::parseAccessDeclaration(DeclarationAST *&node)
1943 if (LA() == T_PUBLIC || LA() == T_PROTECTED || LA() == T_PRIVATE || LA() == T_Q_SIGNALS || LA() == T_Q_SLOTS) {
1944 bool isSignals = LA() == T_Q_SIGNALS;
1945 bool isSlots = LA() == T_Q_SLOTS;
1946 AccessDeclarationAST *ast = new (_pool) AccessDeclarationAST;
1947 ast->access_specifier_token = consumeToken();
1948 if (! isSignals && (LA() == T_Q_SLOTS || isSlots))
1949 ast->slots_token = consumeToken();
1950 match(T_COLON, &ast->colon_token);
1958 Q_PROPERTY(type name
1961 [RESET resetFunction]
1962 [NOTIFY notifySignal]
1970 Note that "type" appears to be any valid type. So these are valid:
1971 Q_PROPERTY(const char *zoo READ zoo)
1972 Q_PROPERTY(const class Blah *blah READ blah)
1974 Furthermore, the only restriction on the order of the items in between the
1975 parenthesis is that the type is the first parameter and the name comes after
1978 bool Parser::parseQtPropertyDeclaration(DeclarationAST *&node)
1981 const bool privateProperty = (LA() == T_Q_PRIVATE_PROPERTY);
1982 if (LA() != T_Q_PROPERTY && !privateProperty)
1985 QtPropertyDeclarationAST *ast = new (_pool)QtPropertyDeclarationAST;
1986 ast->property_specifier_token = consumeToken();
1987 if (LA() == T_LPAREN) {
1988 ast->lparen_token = consumeToken();
1990 if (privateProperty) {
1991 if (parsePostfixExpression(ast->expression)) {
1992 match(T_COMMA, &ast->comma_token);
1995 "expected expression before `%s'",
2001 parseTypeId(ast->type_id);
2003 SimpleNameAST *property_name = new (_pool) SimpleNameAST;
2004 // special case: keywords are allowed for property names!
2005 if (tok().isKeyword()) {
2006 property_name->identifier_token = consumeToken();
2008 match(T_IDENTIFIER, &property_name->identifier_token);
2011 ast->property_name = property_name;
2012 QtPropertyDeclarationItemListAST **iter = &ast->property_declaration_item_list;
2014 if (LA() == T_RPAREN) {
2015 ast->rparen_token = consumeToken();
2018 } else if (LA() == T_IDENTIFIER) {
2019 QtPropertyDeclarationItemAST *item = 0;
2020 switch (peekAtQtContextKeyword()) {
2025 case Token_DESIGNABLE:
2026 case Token_SCRIPTABLE:
2029 unsigned item_name_token = consumeToken();
2030 ExpressionAST *expr = 0;
2031 if (parsePostfixExpression(expr)) {
2032 QtPropertyDeclarationItemAST *bItem =
2033 new (_pool) QtPropertyDeclarationItemAST;
2034 bItem->item_name_token = item_name_token;
2035 bItem->expression = expr;
2039 "expected expression before `%s'",
2045 case Token_CONSTANT:
2047 QtPropertyDeclarationItemAST *fItem = new (_pool) QtPropertyDeclarationItemAST;
2048 fItem->item_name_token = consumeToken();
2054 error(cursor(), "expected `)' before `%s'", tok().spell());
2059 *iter = new (_pool) QtPropertyDeclarationItemListAST;
2060 (*iter)->value = item;
2061 iter = &(*iter)->next;
2066 error(cursor(), "expected `)' before `%s'", tok().spell());
2075 // q-enums-decl ::= 'Q_ENUMS' '(' q-enums-list? ')'
2076 // q-enums-list ::= identifier
2077 // q-enums-list ::= q-enums-list identifier
2079 // Note: Q_ENUMS is a CPP macro with exactly 1 parameter.
2080 // Examples of valid uses:
2082 // Q_ENUMS(Priority)
2083 // Q_ENUMS(Priority Severity)
2084 // so, these are not allowed:
2086 // Q_ENUMS(Priority, Severity)
2087 bool Parser::parseQtEnumDeclaration(DeclarationAST *&node)
2090 if (LA() != T_Q_ENUMS)
2093 QtEnumDeclarationAST *ast = new (_pool) QtEnumDeclarationAST;
2094 ast->enum_specifier_token = consumeToken();
2095 match(T_LPAREN, &ast->lparen_token);
2096 for (NameListAST **iter = &ast->enumerator_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
2097 NameAST *name_ast = 0;
2098 if (!parseName(name_ast))
2100 *iter = new (_pool) NameListAST;
2101 (*iter)->value = name_ast;
2103 match(T_RPAREN, &ast->rparen_token);
2108 // q-flags-decl ::= 'Q_FLAGS' '(' q-flags-list? ')'
2109 // q-flags-list ::= identifier
2110 // q-flags-list ::= q-flags-list identifier
2112 // Note: Q_FLAGS is a CPP macro with exactly 1 parameter.
2113 // Examples of valid uses:
2115 // Q_FLAGS(Orientation)
2116 // Q_FLAGS(Orientation DropActions)
2117 // so, these are not allowed:
2119 // Q_FLAGS(Orientation, DropActions)
2120 bool Parser::parseQtFlags(DeclarationAST *&node)
2123 if (LA() != T_Q_FLAGS)
2126 QtFlagsDeclarationAST *ast = new (_pool) QtFlagsDeclarationAST;
2127 ast->flags_specifier_token = consumeToken();
2128 match(T_LPAREN, &ast->lparen_token);
2129 for (NameListAST **iter = &ast->flag_enums_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
2130 NameAST *name_ast = 0;
2131 if (!parseName(name_ast))
2133 *iter = new (_pool) NameListAST;
2134 (*iter)->value = name_ast;
2136 match(T_RPAREN, &ast->rparen_token);
2141 // class-specifier ::=
2142 // c++-class-specifier
2151 // q-declare-interface
2152 // q-declare-metatype
2158 // q-enums-or-flags ::=
2159 // (Q_ENUMS | Q_FLAGS) LPAREN name+ RPAREN
2162 // Q_CLASS_INFO LPAREN string-literal COMMA STRING_LITERAL RPAREN
2163 // Q_CLASS_INFO LPAREN string-literal COMMA IDENTIFIER LPAREN STRING_LITERAL RPAREN RPAREN
2166 // Q_INTERFACES LPAREN (name q-constraints)* RPAREN
2168 // q-constraints ::=
2170 bool Parser::parseQtInterfaces(DeclarationAST *&node)
2173 if (LA() != T_Q_INTERFACES)
2176 QtInterfacesDeclarationAST *ast = new (_pool) QtInterfacesDeclarationAST;
2177 ast->interfaces_token = consumeToken();
2178 match(T_LPAREN, &ast->lparen_token);
2179 for (QtInterfaceNameListAST **iter = &ast->interface_name_list; LA() && LA() != T_RPAREN; iter = &(*iter)->next) {
2180 NameAST *name_ast = 0;
2181 if (!parseName(name_ast))
2183 *iter = new (_pool) QtInterfaceNameListAST;
2184 (*iter)->value = new (_pool) QtInterfaceNameAST;
2185 (*iter)->value->interface_name = name_ast;
2186 for (NameListAST **iter2 = &(*iter)->value->constraint_list; LA() && LA() == T_COLON; iter2 = &(*iter2)->next) {
2187 /*unsigned colon_token =*/ consumeToken();
2188 NameAST *name_ast2 = 0;
2189 if (!parseName(name_ast2))
2191 *iter2 = new (_pool) NameListAST;
2192 (*iter2)->value = name_ast2;
2196 match(T_RPAREN, &ast->rparen_token);
2201 // q-private-slot ::=
2202 // Q_PRIVATE_SLOT LPAREN IDENTIFIER (LPAREN RPAREN)? COMMA q-function-declaration RPAREN
2204 // q-function-declaration ::=
2205 // decl-specifier-list declarator [+ check for the function-declarator]
2207 // q-declare-interface ::=
2208 // Q_DECLARE_INTERFACE LPAREN name COMMA (STRING_LITERAL | IDENTIFIER) RPAREN
2210 // q-declare-metatype ::=
2211 // Q_DECLARE_METATYPE LPAREN name RPAREN SEMICOLON? [warning]
2213 bool Parser::parseMemberSpecification(DeclarationAST *&node, ClassSpecifierAST *declaringClass)
2220 QtObjectTagAST *ast = new (_pool) QtObjectTagAST;
2221 ast->q_object_token = consumeToken();
2226 case T_Q_PRIVATE_SLOT:
2228 QtPrivateSlotAST *ast = new (_pool) QtPrivateSlotAST;
2229 ast->q_private_slot_token = consumeToken();
2230 match(T_LPAREN, &ast->lparen_token);
2231 match(T_IDENTIFIER, &ast->dptr_token);
2232 if (LA() == T_LPAREN) {
2233 ast->dptr_lparen_token = consumeToken();
2234 match(T_RPAREN, &ast->dptr_rparen_token);
2236 match(T_COMMA, &ast->comma_token);
2237 (void) parseTypeSpecifier(ast->type_specifier_list);
2238 parseDeclarator(ast->declarator, ast->type_specifier_list);
2239 match(T_RPAREN, &ast->rparen_token);
2244 return parseEmptyDeclaration(node);
2247 return parseUsing(node);
2250 return parseTemplateDeclaration(node);
2257 return parseAccessDeclaration(node);
2260 case T_Q_PRIVATE_PROPERTY:
2261 return parseQtPropertyDeclaration(node);
2264 return parseQtEnumDeclaration(node);
2267 return parseQtFlags(node);
2269 case T_Q_INTERFACES:
2270 return parseQtInterfaces(node);
2273 return parseSimpleDeclaration(node, declaringClass);
2277 bool Parser::parseCtorInitializer(CtorInitializerAST *&node)
2280 if (LA() == T_COLON) {
2281 unsigned colon_token = consumeToken();
2283 CtorInitializerAST *ast = new (_pool) CtorInitializerAST;
2284 ast->colon_token = colon_token;
2286 parseMemInitializerList(ast->member_initializer_list);
2288 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
2289 ast->dot_dot_dot_token = consumeToken();
2297 bool Parser::parseElaboratedTypeSpecifier(SpecifierListAST *&node)
2300 if (lookAtClassKey() || LA() == T_ENUM || LA() == T_TYPENAME) {
2301 unsigned classkey_token = consumeToken();
2303 SpecifierListAST *attributes = 0, **attr_ptr = &attributes;
2304 while (LA() == T___ATTRIBUTE__) {
2305 parseAttributeSpecifier(*attr_ptr);
2306 attr_ptr = &(*attr_ptr)->next;
2310 if (parseName(name)) {
2311 ElaboratedTypeSpecifierAST *ast = new (_pool) ElaboratedTypeSpecifierAST;
2312 ast->classkey_token = classkey_token;
2313 ast->attribute_list = attributes;
2315 node = new (_pool) SpecifierListAST(ast);
2322 bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node)
2325 if (LA() == T_THROW) {
2326 ExceptionSpecificationAST *ast = new (_pool) ExceptionSpecificationAST;
2327 ast->throw_token = consumeToken();
2328 if (LA() == T_LPAREN)
2329 ast->lparen_token = consumeToken();
2330 if (LA() == T_DOT_DOT_DOT)
2331 ast->dot_dot_dot_token = consumeToken();
2333 parseTypeIdList(ast->type_id_list);
2334 if (LA() == T_RPAREN)
2335 ast->rparen_token = consumeToken();
2342 bool Parser::parseEnumerator(EnumeratorListAST *&node)
2345 if (LA() == T_IDENTIFIER) {
2346 EnumeratorAST *ast = new (_pool) EnumeratorAST;
2347 ast->identifier_token = consumeToken();
2349 if (LA() == T_EQUAL) {
2350 ast->equal_token = consumeToken();
2351 parseConstantExpression(ast->expression);
2354 node = new (_pool) EnumeratorListAST;
2361 bool Parser::parseInitDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list,
2362 ClassSpecifierAST *declaringClass) // ### rewrite me
2366 if (declaringClass && LA() == T_COLON) {
2367 // anonymous bit-field declaration.
2369 } else if (! parseDeclarator(node, decl_specifier_list, declaringClass)) {
2373 if (LA() == T_ASM && LA(2) == T_LPAREN) { // ### FIXME
2376 if (skip(T_LPAREN, T_RPAREN))
2380 if (declaringClass && LA() == T_COLON
2381 && (! node || ! node->postfix_declarator_list)) {
2382 unsigned colon_token = consumeToken();
2383 ExpressionAST *expression = 0;
2384 if (parseConstantExpression(expression) && (LA() == T_COMMA ||
2385 LA() == T_SEMICOLON)) {
2386 // recognized a bitfielddeclarator.
2388 node = new (_pool) DeclaratorAST;
2389 node->initializer = expression;
2392 rewind(colon_token);
2393 } else if (node->core_declarator && (LA() == T_EQUAL || (! declaringClass && LA() == T_LPAREN))) {
2394 parseInitializer(node->initializer, &node->equal_token);
2399 bool Parser::parseBaseClause(BaseSpecifierListAST *&node)
2403 if (LA() == T_COLON) {
2404 consumeToken(); // ### remove me
2406 BaseSpecifierListAST **ast = &node;
2407 if (parseBaseSpecifier(*ast)) {
2408 ast = &(*ast)->next;
2410 while (LA() == T_COMMA) {
2411 consumeToken(); // consume T_COMMA
2413 if (parseBaseSpecifier(*ast))
2414 ast = &(*ast)->next;
2423 bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token)
2427 return parseInitializer0x(node, equals_token);
2430 bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token)
2434 if ((_cxx0xEnabled && LA() == T_LBRACE) || LA() == T_EQUAL) {
2435 if (LA() == T_EQUAL)
2436 *equals_token = cursor();
2438 return parseBraceOrEqualInitializer0x(node);
2441 else if (LA() == T_LPAREN) {
2442 return parsePrimaryExpression(node);
2448 bool Parser::parseBraceOrEqualInitializer0x(ExpressionAST *&node)
2450 if (LA() == T_EQUAL) {
2452 parseInitializerClause0x(node);
2455 } else if (LA() == T_LBRACE) {
2456 return parseBracedInitList0x(node);
2463 bool Parser::parseInitializerClause0x(ExpressionAST *&node)
2465 if (LA() == T_LBRACE)
2466 return parseBracedInitList0x(node);
2468 parseAssignmentExpression(node);
2472 bool Parser::parseInitializerList0x(ExpressionListAST *&node)
2474 ExpressionListAST **expression_list_ptr = &node;
2475 ExpressionAST *expression = 0;
2477 if (parseInitializerClause0x(expression)) {
2478 *expression_list_ptr = new (_pool) ExpressionListAST;
2479 (*expression_list_ptr)->value = expression;
2480 expression_list_ptr = &(*expression_list_ptr)->next;
2482 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN))
2483 consumeToken(); // ### create an argument pack
2485 while (LA() == T_COMMA && LA(2) != T_RBRACE) {
2486 consumeToken(); // consume T_COMMA
2488 if (parseInitializerClause0x(expression)) {
2489 *expression_list_ptr = new (_pool) ExpressionListAST;
2490 (*expression_list_ptr)->value = expression;
2492 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN))
2493 consumeToken(); // ### create an argument pack
2495 expression_list_ptr = &(*expression_list_ptr)->next;
2503 bool Parser::parseBracedInitList0x(ExpressionAST *&node)
2505 if (LA() != T_LBRACE)
2508 BracedInitializerAST *ast = new (_pool) BracedInitializerAST;
2509 ast->lbrace_token = consumeToken();
2511 parseInitializerList0x(ast->expression_list);
2513 if (LA() == T_COMMA && LA(2) == T_RBRACE)
2514 ast->comma_token = consumeToken();
2516 match(T_RBRACE, &ast->rbrace_token);
2521 bool Parser::parseMemInitializerList(MemInitializerListAST *&node)
2524 MemInitializerListAST **initializer = &node;
2526 if (parseMemInitializer(*initializer)) {
2527 initializer = &(*initializer)->next;
2531 if (LA() == T_LBRACE)
2534 else if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && LA(2) == T_LBRACE)
2537 else if (LA() == T_COMMA || (LA() == T_IDENTIFIER && (LA(2) == T_LPAREN || LA(2) == T_COLON_COLON))) {
2538 if (LA() != T_COMMA)
2539 error(cursor(), "expected `,'");
2543 if (parseMemInitializer(*initializer))
2544 initializer = &(*initializer)->next;
2546 error(cursor(), "expected a member initializer");
2551 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT) {
2552 if (LA(2) != T_LBRACE)
2553 error(cursor(), "expected `{'");
2555 } else if (LA() != T_LBRACE) {
2556 error(cursor(), "expected `{'");
2565 bool Parser::parseMemInitializer(MemInitializerListAST *&node)
2569 if (! parseName(name))
2572 MemInitializerAST *ast = new (_pool) MemInitializerAST;
2574 match(T_LPAREN, &ast->lparen_token);
2575 parseExpressionList(ast->expression_list);
2576 match(T_RPAREN, &ast->rparen_token);
2578 node = new (_pool) MemInitializerListAST;
2583 bool Parser::parseTypeIdList(ExpressionListAST *&node)
2586 ExpressionListAST **expression_list_ptr = &node;
2587 ExpressionAST *typeId = 0;
2588 if (parseTypeId(typeId)) {
2589 *expression_list_ptr = new (_pool) ExpressionListAST;
2590 (*expression_list_ptr)->value = typeId;
2591 expression_list_ptr = &(*expression_list_ptr)->next;
2593 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
2594 consumeToken(); // ### store this token
2596 while (LA() == T_COMMA) {
2599 if (parseTypeId(typeId)) {
2600 *expression_list_ptr = new (_pool) ExpressionListAST;
2601 (*expression_list_ptr)->value = typeId;
2602 expression_list_ptr = &(*expression_list_ptr)->next;
2604 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
2605 consumeToken(); // ### store this token
2614 bool Parser::parseExpressionList(ExpressionListAST *&node)
2618 #ifdef CPLUSPLUS_WITH_CXXOX_INITIALIZER_LIST
2620 return parseInitializerList0x(node);
2624 ExpressionListAST **expression_list_ptr = &node;
2625 ExpressionAST *expression = 0;
2626 if (parseAssignmentExpression(expression)) {
2627 *expression_list_ptr = new (_pool) ExpressionListAST;
2628 (*expression_list_ptr)->value = expression;
2629 expression_list_ptr = &(*expression_list_ptr)->next;
2630 while (LA() == T_COMMA) {
2631 consumeToken(); // consume T_COMMA
2633 if (parseAssignmentExpression(expression)) {
2634 *expression_list_ptr = new (_pool) ExpressionListAST;
2635 (*expression_list_ptr)->value = expression;
2636 expression_list_ptr = &(*expression_list_ptr)->next;
2645 bool Parser::parseBaseSpecifier(BaseSpecifierListAST *&node)
2648 BaseSpecifierAST *ast = new (_pool) BaseSpecifierAST;
2650 if (LA() == T_VIRTUAL) {
2651 ast->virtual_token = consumeToken();
2654 if (tk == T_PUBLIC || tk == T_PROTECTED || tk == T_PRIVATE)
2655 ast->access_specifier_token = consumeToken();
2658 if (tk == T_PUBLIC || tk == T_PROTECTED || tk == T_PRIVATE)
2659 ast->access_specifier_token = consumeToken();
2661 if (LA() == T_VIRTUAL)
2662 ast->virtual_token = consumeToken();
2665 parseName(ast->name);
2667 error(cursor(), "expected class-name");
2669 node = new (_pool) BaseSpecifierListAST;
2674 bool Parser::parseInitializerList(ExpressionListAST *&node)
2677 ExpressionListAST **initializer_ptr = &node;
2678 ExpressionAST *initializer = 0;
2679 if (parseInitializerClause(initializer)) {
2680 *initializer_ptr = new (_pool) ExpressionListAST;
2681 (*initializer_ptr)->value = initializer;
2682 initializer_ptr = &(*initializer_ptr)->next;
2683 while (LA() == T_COMMA) {
2684 consumeToken(); // consume T_COMMA
2686 parseInitializerClause(initializer);
2687 *initializer_ptr = new (_pool) ExpressionListAST;
2688 (*initializer_ptr)->value = initializer;
2689 initializer_ptr = &(*initializer_ptr)->next;
2693 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
2694 consumeToken(); // ### store this token
2699 bool Parser::parseInitializerClause(ExpressionAST *&node)
2702 if (LA() == T_LBRACE) {
2703 ArrayInitializerAST *ast = new (_pool) ArrayInitializerAST;
2704 ast->lbrace_token = consumeToken();
2705 parseInitializerList(ast->expression_list);
2706 match(T_RBRACE, &ast->rbrace_token);
2710 return parseAssignmentExpression(node);
2713 bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId)
2716 if (LA() == T_TILDE && LA(2) == T_IDENTIFIER) {
2717 DestructorNameAST *ast = new (_pool) DestructorNameAST;
2718 ast->tilde_token = consumeToken();
2719 ast->identifier_token = consumeToken();
2722 } else if (LA() == T_OPERATOR) {
2723 unsigned operator_token = cursor();
2724 if (parseOperatorFunctionId(node))
2726 rewind(operator_token);
2727 return parseConversionFunctionId(node);
2728 } else if (LA() == T_IDENTIFIER) {
2729 unsigned identifier_token = cursor();
2730 if (acceptTemplateId && LA(2) == T_LESS && parseTemplateId(node)) {
2731 if (! _templateArguments || (LA() == T_COMMA || LA() == T_GREATER ||
2732 LA() == T_LPAREN || LA() == T_RPAREN ||
2733 LA() == T_STAR || LA() == T_AMPER || // ptr-operators
2734 LA() == T_COLON_COLON))
2737 rewind(identifier_token);
2738 SimpleNameAST *ast = new (_pool) SimpleNameAST;
2739 ast->identifier_token = consumeToken();
2742 } else if (LA() == T_TEMPLATE) {
2743 unsigned template_token = consumeToken();
2744 if (parseTemplateId(node, template_token))
2746 rewind(template_token);
2751 bool Parser::parseStringLiteral(ExpressionAST *&node)
2754 if (! (LA() == T_STRING_LITERAL || LA() == T_WIDE_STRING_LITERAL))
2757 StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
2759 while (LA() == T_STRING_LITERAL || LA() == T_WIDE_STRING_LITERAL) {
2760 *ast = new (_pool) StringLiteralAST;
2761 (*ast)->literal_token = consumeToken();
2762 ast = &(*ast)->next;
2767 bool Parser::parseExpressionStatement(StatementAST *&node)
2770 if (LA() == T_SEMICOLON) {
2771 ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
2772 match(T_SEMICOLON, &ast->semicolon_token);
2777 const bool wasInExpressionStatement = _inExpressionStatement;
2778 _inExpressionStatement = true;
2780 // switch to the temp pool
2781 MemoryPool *previousPool = _pool;
2782 _pool = &_expressionStatementTempPool;
2784 bool parsed = false;
2786 ExpressionAST *expression = 0;
2787 if (parseExpression(expression)) {
2788 ExpressionStatementAST *ast = new (previousPool) ExpressionStatementAST;
2790 ast->expression = expression->clone(previousPool);
2791 match(T_SEMICOLON, &ast->semicolon_token);
2796 _inExpressionStatement = wasInExpressionStatement;
2798 if (! _inExpressionStatement) {
2799 // rewind the memory pool after parsing a toplevel expression statement.
2800 _expressionStatementTempPool.reset();
2804 _pool = previousPool;
2808 bool Parser::parseStatement(StatementAST *&node)
2813 return parseWhileStatement(node);
2816 return parseDoStatement(node);
2819 return parseForeachStatement(node);
2822 return parseForStatement(node);
2825 return parseIfStatement(node);
2828 return parseSwitchStatement(node);
2831 return parseTryBlockStatement(node);
2835 return parseLabeledStatement(node);
2838 return parseBreakStatement(node);
2841 return parseContinueStatement(node);
2844 return parseGotoStatement(node);
2847 return parseReturnStatement(node);
2850 return parseCompoundStatement(node);
2856 case T_CLASS: case T_STRUCT: case T_UNION:
2857 return parseDeclarationStatement(node);
2860 ExpressionStatementAST *ast = new (_pool) ExpressionStatementAST;
2861 ast->semicolon_token = consumeToken();
2866 case T_AT_SYNCHRONIZED:
2867 return objCEnabled() && parseObjCSynchronizedStatement(node);
2871 QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST;
2872 ast->q_token = consumeToken();
2873 match(T_LPAREN, &ast->lparen_token);
2874 parseTypeId(ast->type_id);
2875 match(T_RPAREN, &ast->rparen_token);
2880 if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
2881 return parseLabeledStatement(node);
2883 return parseExpressionOrDeclarationStatement(node);
2885 return false; //Avoid compiler warning
2888 bool Parser::parseBreakStatement(StatementAST *&node)
2891 if (LA() == T_BREAK) {
2892 BreakStatementAST *ast = new (_pool) BreakStatementAST;
2893 ast->break_token = consumeToken();
2894 match(T_SEMICOLON, &ast->semicolon_token);
2901 bool Parser::parseContinueStatement(StatementAST *&node)
2904 if (LA() == T_CONTINUE) {
2905 ContinueStatementAST *ast = new (_pool) ContinueStatementAST;
2906 ast->continue_token = consumeToken();
2907 match(T_SEMICOLON, &ast->semicolon_token);
2914 bool Parser::parseGotoStatement(StatementAST *&node)
2917 if (LA() == T_GOTO) {
2918 GotoStatementAST *ast = new (_pool) GotoStatementAST;
2919 ast->goto_token = consumeToken();
2920 match(T_IDENTIFIER, &ast->identifier_token);
2921 match(T_SEMICOLON, &ast->semicolon_token);
2928 bool Parser::parseReturnStatement(StatementAST *&node)
2931 if (LA() == T_RETURN) {
2932 ReturnStatementAST *ast = new (_pool) ReturnStatementAST;
2933 ast->return_token = consumeToken();
2934 parseExpression(ast->expression);
2935 match(T_SEMICOLON, &ast->semicolon_token);
2942 bool Parser::maybeAmbiguousStatement(DeclarationStatementAST *ast, StatementAST *&node)
2944 const unsigned start = ast->firstToken();
2945 const unsigned end = ast->lastToken();
2946 const bool blocked = blockErrors(true);
2948 bool maybeAmbiguous = false;
2950 StatementAST *stmt = 0;
2951 if (parseExpressionStatement(stmt)) {
2952 if (stmt->firstToken() == start && stmt->lastToken() == end) {
2953 maybeAmbiguous = true;
2959 (void) blockErrors(blocked);
2960 return maybeAmbiguous;
2963 bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node)
2967 if (LA() == T_SEMICOLON)
2968 return parseExpressionStatement(node);
2970 const unsigned start = cursor();
2972 if (lookAtCVQualifier() || lookAtStorageClassSpecifier() || lookAtBuiltinTypeSpecifier() || LA() == T_TYPENAME || LA() == T_ENUM || lookAtClassKey())
2973 return parseDeclarationStatement(node);
2975 if (LA() == T_IDENTIFIER || (LA() == T_COLON_COLON && LA(2) == T_IDENTIFIER)) {
2976 const bool blocked = blockErrors(true);
2978 ExpressionAST *expression = 0;
2979 const bool hasExpression = parseExpression(expression);
2980 const unsigned afterExpression = cursor();
2982 if (hasExpression/* && LA() == T_SEMICOLON*/) {
2983 //const unsigned semicolon_token = consumeToken();
2984 unsigned semicolon_token = 0;
2985 if (LA() == T_SEMICOLON)
2986 semicolon_token = cursor();
2988 ExpressionStatementAST *as_expression = new (_pool) ExpressionStatementAST;
2989 as_expression->expression = expression;
2990 as_expression->semicolon_token = semicolon_token;
2991 node = as_expression; // well, at least for now.
2993 bool invalidAssignment = false;
2994 if (BinaryExpressionAST *binary = expression->asBinaryExpression()) {
2995 const int binop = _translationUnit->tokenKind(binary->binary_op_token);
2996 if (binop == T_EQUAL) {
2997 if (! binary->left_expression->asBinaryExpression()) {
2998 (void) blockErrors(blocked);
2999 node = as_expression;
3000 match(T_SEMICOLON, &as_expression->semicolon_token);
3003 invalidAssignment = true;
3006 } else if (CallAST *call = expression->asCall()) {
3007 if (call->base_expression->asIdExpression() != 0) {
3008 (void) blockErrors(blocked);
3009 node = as_expression;
3010 match(T_SEMICOLON, &as_expression->semicolon_token);
3017 DeclarationAST *declaration = 0;
3018 if (parseSimpleDeclaration(declaration)) {
3019 DeclarationStatementAST *as_declaration = new (_pool) DeclarationStatementAST;
3020 as_declaration->declaration = declaration;
3022 SimpleDeclarationAST *simple = declaration->asSimpleDeclaration();
3023 if (! semicolon_token || invalidAssignment || semicolon_token != simple->semicolon_token ||
3024 (simple->decl_specifier_list != 0 && simple->declarator_list != 0)) {
3025 node = as_declaration;
3026 (void) blockErrors(blocked);
3030 ExpressionOrDeclarationStatementAST *ast = new (_pool) ExpressionOrDeclarationStatementAST;
3031 ast->declaration = as_declaration;
3032 ast->expression = as_expression;
3034 (void) blockErrors(blocked);
3038 (void) blockErrors(blocked);
3040 rewind(afterExpression);
3041 match(T_SEMICOLON, &as_expression->semicolon_token);
3046 (void) blockErrors(blocked);
3048 return parseDeclarationStatement(node);
3052 return parseExpressionStatement(node);
3055 bool Parser::parseCondition(ExpressionAST *&node)
3058 unsigned start = cursor();
3060 bool blocked = blockErrors(true);
3061 SpecifierListAST *type_specifier = 0;
3062 if (parseTypeSpecifier(type_specifier)) {
3063 DeclaratorAST *declarator = 0;
3064 if (parseInitDeclarator(declarator, type_specifier, /*declaringClass=*/ 0)) {
3065 if (declarator->initializer && declarator->equal_token) {
3066 ConditionAST *ast = new (_pool) ConditionAST;
3067 ast->type_specifier_list = type_specifier;
3068 ast->declarator = declarator;
3070 blockErrors(blocked);
3076 blockErrors(blocked);
3078 return parseExpression(node);
3081 bool Parser::parseWhileStatement(StatementAST *&node)
3084 if (LA() == T_WHILE) {
3085 WhileStatementAST *ast = new (_pool) WhileStatementAST;
3086 ast->while_token = consumeToken();
3087 match(T_LPAREN, &ast->lparen_token);
3088 parseCondition(ast->condition);
3089 match(T_RPAREN, &ast->rparen_token);
3090 parseStatement(ast->statement);
3097 bool Parser::parseDoStatement(StatementAST *&node)
3101 DoStatementAST *ast = new (_pool) DoStatementAST;
3102 ast->do_token = consumeToken();
3103 parseStatement(ast->statement);
3104 match(T_WHILE, &ast->while_token);
3105 match(T_LPAREN, &ast->lparen_token);
3106 parseExpression(ast->expression);
3107 match(T_RPAREN, &ast->rparen_token);
3108 match(T_SEMICOLON, &ast->semicolon_token);
3115 bool Parser::parseForeachStatement(StatementAST *&node)
3118 if (LA() == T_Q_FOREACH) {
3119 ForeachStatementAST *ast = new (_pool) ForeachStatementAST;
3120 ast->foreach_token = consumeToken();
3121 match(T_LPAREN, &ast->lparen_token);
3123 unsigned startOfTypeSpecifier = cursor();
3124 bool blocked = blockErrors(true);
3126 if (parseTypeSpecifier(ast->type_specifier_list))
3127 parseDeclarator(ast->declarator, ast->type_specifier_list);
3129 if (! ast->type_specifier_list || ! ast->declarator) {
3130 ast->type_specifier_list = 0;
3131 ast->declarator = 0;
3133 blockErrors(blocked);
3134 rewind(startOfTypeSpecifier);
3135 parseAssignmentExpression(ast->initializer);
3138 blockErrors(blocked);
3140 match(T_COMMA, &ast->comma_token);
3141 parseExpression(ast->expression);
3142 match(T_RPAREN, &ast->rparen_token);
3143 parseStatement(ast->statement);
3151 bool Parser::parseForStatement(StatementAST *&node)
3157 unsigned for_token = consumeToken();
3158 unsigned lparen_token = 0;
3159 match(T_LPAREN, &lparen_token);
3161 unsigned startOfTypeSpecifier = cursor();
3162 bool blocked = blockErrors(true);
3164 if (objCEnabled()) {
3165 ObjCFastEnumerationAST *ast = new (_pool) ObjCFastEnumerationAST;
3166 ast->for_token = for_token;
3167 ast->lparen_token = lparen_token;
3169 if (parseTypeSpecifier(ast->type_specifier_list))
3170 parseDeclarator(ast->declarator, ast->type_specifier_list);
3172 if ((ast->type_specifier_list || ast->declarator) && !peekAtObjCContextKeyword(Token_in)) {
3173 // woops, probably parsed too much: "in" got parsed as a declarator. Let's redo it:
3174 ast->type_specifier_list = 0;
3175 ast->declarator = 0;
3177 rewind(startOfTypeSpecifier);
3178 parseDeclarator(ast->declarator, ast->type_specifier_list);
3181 if (! ast->type_specifier_list || ! ast->declarator) {
3182 ast->type_specifier_list = 0;
3183 ast->declarator = 0;
3185 rewind(startOfTypeSpecifier);
3186 parseAssignmentExpression(ast->initializer);
3189 if (parseObjCContextKeyword(Token_in, ast->in_token)) {
3190 blockErrors(blocked);
3192 parseExpression(ast->fast_enumeratable_expression);
3193 match(T_RPAREN, &ast->rparen_token);
3194 parseStatement(ast->statement);
3200 // there was no "in" token, so we continue with a normal for-statement
3201 rewind(startOfTypeSpecifier);
3204 blockErrors(blocked);
3206 // Normal C/C++ for-statement parsing
3207 ForStatementAST *ast = new (_pool) ForStatementAST;
3209 ast->for_token = for_token;
3210 ast->lparen_token = lparen_token;
3211 parseForInitStatement(ast->initializer);
3212 parseCondition(ast->condition);
3213 match(T_SEMICOLON, &ast->semicolon_token);
3214 parseExpression(ast->expression);
3215 match(T_RPAREN, &ast->rparen_token);
3216 parseStatement(ast->statement);
3222 bool Parser::parseForInitStatement(StatementAST *&node)
3225 return parseExpressionOrDeclarationStatement(node);
3228 bool Parser::parseCompoundStatement(StatementAST *&node)
3231 if (LA() == T_LBRACE) {
3232 CompoundStatementAST *ast = new (_pool) CompoundStatementAST;
3233 ast->lbrace_token = consumeToken();
3235 // ### TODO: the GNU "local label" extension: "__label__ X, Y, Z;"
3236 // These are only allowed at the start of a compound stmt regardless of the language.
3238 StatementListAST **statement_ptr = &ast->statement_list;
3239 while (int tk = LA()) {
3243 unsigned start_statement = cursor();
3244 StatementAST *statement = 0;
3245 if (! parseStatement(statement)) {
3246 rewind(start_statement + 1);
3247 skipUntilStatement();
3249 *statement_ptr = new (_pool) StatementListAST;
3250 (*statement_ptr)->value = statement;
3251 statement_ptr = &(*statement_ptr)->next;
3254 match(T_RBRACE, &ast->rbrace_token);
3261 bool Parser::parseIfStatement(StatementAST *&node)
3265 IfStatementAST *ast = new (_pool) IfStatementAST;
3266 ast->if_token = consumeToken();
3267 match(T_LPAREN, &ast->lparen_token);
3268 parseCondition(ast->condition);
3269 match(T_RPAREN, &ast->rparen_token);
3270 if (! parseStatement(ast->statement))
3271 error(cursor(), "expected statement");
3272 if (LA() == T_ELSE) {
3273 ast->else_token = consumeToken();
3274 if (! parseStatement(ast->else_statement))
3275 error(cursor(), "expected statement");
3283 bool Parser::parseSwitchStatement(StatementAST *&node)
3286 if (LA() == T_SWITCH) {
3287 SwitchStatementAST *ast = new (_pool) SwitchStatementAST;
3288 ast->switch_token = consumeToken();
3289 match(T_LPAREN, &ast->lparen_token);
3290 parseCondition(ast->condition);
3291 match(T_RPAREN, &ast->rparen_token);
3292 parseStatement(ast->statement);
3299 bool Parser::parseLabeledStatement(StatementAST *&node)
3304 if (LA(2) == T_COLON) {
3305 LabeledStatementAST *ast = new (_pool) LabeledStatementAST;
3306 ast->label_token = consumeToken();
3307 ast->colon_token = consumeToken();
3308 parseStatement(ast->statement);
3315 LabeledStatementAST *ast = new (_pool) LabeledStatementAST;
3316 ast->label_token = consumeToken();
3317 match(T_COLON, &ast->colon_token);
3318 parseStatement(ast->statement);
3324 CaseStatementAST *ast = new (_pool) CaseStatementAST;
3325 ast->case_token = consumeToken();
3326 parseConstantExpression(ast->expression);
3327 match(T_COLON, &ast->colon_token);
3328 parseStatement(ast->statement);
3339 bool Parser::parseBlockDeclaration(DeclarationAST *&node)
3344 return parseUsing(node);
3347 return parseAsmDefinition(node);
3350 return parseNamespaceAliasDefinition(node);
3353 return parseSimpleDeclaration(node);
3358 bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node)
3361 if (LA() == T_NAMESPACE && LA(2) == T_IDENTIFIER && LA(3) == T_EQUAL) {
3362 NamespaceAliasDefinitionAST *ast = new (_pool) NamespaceAliasDefinitionAST;
3363 ast->namespace_token = consumeToken();
3364 ast->namespace_name_token = consumeToken();
3365 ast->equal_token = consumeToken();
3366 parseName(ast->name);
3367 match(T_SEMICOLON, &ast->semicolon_token);
3374 bool Parser::parseDeclarationStatement(StatementAST *&node)
3377 unsigned start = cursor();
3378 DeclarationAST *declaration = 0;
3379 if (! parseBlockDeclaration(declaration))
3382 if (SimpleDeclarationAST *simpleDeclaration = declaration->asSimpleDeclaration()) {
3383 if (! simpleDeclaration->decl_specifier_list) {
3389 DeclarationStatementAST *ast = new (_pool) DeclarationStatementAST;
3390 ast->declaration = declaration;
3395 bool Parser::lookAtCVQualifier() const
3406 bool Parser::lookAtFunctionSpecifier() const
3418 bool Parser::lookAtStorageClassSpecifier() const
3433 bool Parser::lookAtBuiltinTypeSpecifier() const
3451 case T___ATTRIBUTE__:
3458 bool Parser::lookAtClassKey() const
3470 bool Parser::parseAttributeSpecifier(SpecifierListAST *&node)
3473 if (LA() != T___ATTRIBUTE__)
3476 AttributeSpecifierAST *ast = new (_pool) AttributeSpecifierAST;
3477 ast->attribute_token = consumeToken();
3478 match(T_LPAREN, &ast->first_lparen_token);
3479 match(T_LPAREN, &ast->second_lparen_token);
3480 parseAttributeList(ast->attribute_list);
3481 match(T_RPAREN, &ast->first_rparen_token);
3482 match(T_RPAREN, &ast->second_rparen_token);
3483 node = new (_pool) SpecifierListAST(ast);
3487 bool Parser::parseAttributeList(AttributeListAST *&node)
3491 AttributeListAST **iter = &node;
3492 while (LA() == T_CONST || LA() == T_IDENTIFIER) {
3493 *iter = new (_pool) AttributeListAST;
3495 if (LA() == T_CONST) {
3496 AttributeAST *attr = new (_pool) AttributeAST;
3497 attr->identifier_token = consumeToken();
3499 (*iter)->value = attr;
3500 iter = &(*iter)->next;
3501 } else if (LA() == T_IDENTIFIER) {
3502 AttributeAST *attr = new (_pool) AttributeAST;
3503 attr->identifier_token = consumeToken();
3504 if (LA() == T_LPAREN) {
3505 attr->lparen_token = consumeToken();
3506 parseExpressionList(attr->expression_list);
3507 match(T_RPAREN, &attr->rparen_token);
3510 (*iter)->value = attr;
3511 iter = &(*iter)->next;
3514 if (LA() != T_COMMA)
3517 consumeToken(); // skip T_COMMA
3523 bool Parser::parseBuiltinTypeSpecifier(SpecifierListAST *&node)
3526 if (LA() == T___ATTRIBUTE__) {
3527 return parseAttributeSpecifier(node);
3528 } else if (LA() == T___TYPEOF__) {
3529 TypeofSpecifierAST *ast = new (_pool) TypeofSpecifierAST;
3530 ast->typeof_token = consumeToken();
3531 if (LA() == T_LPAREN) {
3532 unsigned lparen_token = consumeToken();
3533 if (parseTypeId(ast->expression) && LA() == T_RPAREN) {
3534 ast->lparen_token = lparen_token;
3535 ast->rparen_token = consumeToken();
3536 node = new (_pool) SpecifierListAST(ast);
3539 rewind(lparen_token);
3541 parseUnaryExpression(ast->expression);
3542 node = new (_pool) SpecifierListAST(ast);
3544 } else if (lookAtBuiltinTypeSpecifier()) {
3545 SimpleSpecifierAST *ast = new (_pool) SimpleSpecifierAST;
3546 ast->specifier_token = consumeToken();
3547 node = new (_pool) SpecifierListAST(ast);
3553 bool Parser::parseSimpleDeclaration(DeclarationAST *&node, ClassSpecifierAST *declaringClass)
3556 unsigned qt_invokable_token = 0;
3557 if (declaringClass && (LA() == T_Q_SIGNAL || LA() == T_Q_SLOT || LA() == T_Q_INVOKABLE))
3558 qt_invokable_token = consumeToken();
3560 // parse a simple declaration, a function definition,
3561 // or a contructor declaration.
3562 bool has_type_specifier = false;
3563 bool has_complex_type_specifier = false;
3564 unsigned startOfNamedTypeSpecifier = 0;
3565 NameAST *named_type_specifier = 0;
3566 SpecifierListAST *decl_specifier_seq = 0,
3567 **decl_specifier_seq_ptr = &decl_specifier_seq;
3569 if (lookAtCVQualifier() || lookAtFunctionSpecifier()
3570 || lookAtStorageClassSpecifier()) {
3571 SimpleSpecifierAST *spec = new (_pool) SimpleSpecifierAST;
3572 spec->specifier_token = consumeToken();
3573 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
3574 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3575 } else if (LA() == T___ATTRIBUTE__) {
3576 parseAttributeSpecifier(*decl_specifier_seq_ptr);
3577 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3578 } else if (! named_type_specifier && ! has_complex_type_specifier && lookAtBuiltinTypeSpecifier()) {
3579 parseBuiltinTypeSpecifier(*decl_specifier_seq_ptr);
3580 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3581 has_type_specifier = true;
3582 } else if (! has_type_specifier && (LA() == T_COLON_COLON ||
3583 LA() == T_IDENTIFIER)) {
3584 startOfNamedTypeSpecifier = cursor();
3585 if (parseName(named_type_specifier)) {
3587 if (LA() == T_LPAREN && identifier(named_type_specifier) == className(declaringClass)) {
3588 // looks like a constructor declaration
3589 rewind(startOfNamedTypeSpecifier);
3594 NamedTypeSpecifierAST *spec = new (_pool) NamedTypeSpecifierAST;
3595 spec->name = named_type_specifier;
3596 *decl_specifier_seq_ptr = new (_pool) SpecifierListAST(spec);
3597 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3598 has_type_specifier = true;
3600 rewind(startOfNamedTypeSpecifier);
3603 } else if (! has_type_specifier && LA() == T_ENUM) {
3604 unsigned startOfTypeSpecifier = cursor();
3605 if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) || LA() == T_LBRACE) {
3606 rewind(startOfTypeSpecifier);
3607 if (! parseEnumSpecifier(*decl_specifier_seq_ptr)) {
3608 error(startOfTypeSpecifier,
3609 "expected an enum specifier");
3612 has_complex_type_specifier = true;
3614 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3615 has_type_specifier = true;
3616 } else if (! has_type_specifier && LA() == T_TYPENAME) {
3617 unsigned startOfElaboratedTypeSpecifier = cursor();
3618 if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr)) {
3619 error(startOfElaboratedTypeSpecifier,
3620 "expected an elaborated type specifier");
3623 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3624 has_type_specifier = true;
3625 } else if (! has_type_specifier && lookAtClassKey()) {
3626 unsigned startOfTypeSpecifier = cursor();
3627 if (! parseElaboratedTypeSpecifier(*decl_specifier_seq_ptr) ||
3628 (LA() == T_COLON || LA() == T_LBRACE || (LA(0) == T_IDENTIFIER && LA(1) == T_IDENTIFIER &&
3629 (LA(2) == T_COLON || LA(2) == T_LBRACE)))) {
3630 rewind(startOfTypeSpecifier);
3631 if (! parseClassSpecifier(*decl_specifier_seq_ptr)) {
3632 error(startOfTypeSpecifier,
3633 "wrong type specifier");
3636 has_complex_type_specifier = true;
3638 decl_specifier_seq_ptr = &(*decl_specifier_seq_ptr)->next;
3639 has_type_specifier = true;
3644 DeclaratorListAST *declarator_list = 0,
3645 **declarator_ptr = &declarator_list;
3647 DeclaratorAST *declarator = 0;
3649 if (LA() != T_SEMICOLON) {
3650 const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier);
3651 if (! parseInitDeclarator(declarator, decl_specifier_seq, declaringClass) && maybeCtor) {
3652 rewind(startOfNamedTypeSpecifier);
3653 named_type_specifier = 0;
3654 // pop the named type specifier from the decl-specifier-seq
3655 SpecifierListAST **spec_ptr = &decl_specifier_seq;
3656 for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) {
3657 if (! (*spec_ptr)->next) {
3662 if (! parseInitDeclarator(declarator, decl_specifier_seq, declaringClass))
3667 // if there is no valid declarator
3668 // and it doesn't look like a fwd or a class declaration
3669 // then it's not a declarations
3670 if (! declarator && ! maybeForwardOrClassDeclaration(decl_specifier_seq))
3673 DeclaratorAST *firstDeclarator = declarator;
3676 *declarator_ptr = new (_pool) DeclaratorListAST;
3677 (*declarator_ptr)->value = declarator;
3678 declarator_ptr = &(*declarator_ptr)->next;
3681 if (LA() == T_COMMA || LA() == T_SEMICOLON || has_complex_type_specifier) {
3682 while (LA() == T_COMMA) {
3683 consumeToken(); // consume T_COMMA
3686 if (parseInitDeclarator(declarator, decl_specifier_seq, declaringClass)) {
3687 *declarator_ptr = new (_pool) DeclaratorListAST;
3688 (*declarator_ptr)->value = declarator;
3689 declarator_ptr = &(*declarator_ptr)->next;
3692 SimpleDeclarationAST *ast = new (_pool) SimpleDeclarationAST;
3693 ast->qt_invokable_token = qt_invokable_token;
3694 ast->decl_specifier_list = decl_specifier_seq;
3695 ast->declarator_list = declarator_list;
3696 match(T_SEMICOLON, &ast->semicolon_token);
3699 } else if (! _inFunctionBody && declarator && (LA() == T_COLON || LA() == T_LBRACE || LA() == T_TRY)) {
3700 CtorInitializerAST *ctor_initializer = 0;
3701 bool hasCtorInitializer = false;
3702 if (LA() == T_COLON) {
3703 hasCtorInitializer = true;
3704 parseCtorInitializer(ctor_initializer);
3706 if (LA() != T_LBRACE) {
3707 const unsigned pos = cursor();
3709 for (int n = 0; n < 3 && LA(); consumeToken(), ++n)
3710 if (LA() == T_LBRACE)
3713 if (LA() != T_LBRACE) {
3714 error(pos, "unexpected token `%s'", _translationUnit->spell(pos));
3720 if (LA() == T_LBRACE || hasCtorInitializer) {
3721 FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
3722 ast->qt_invokable_token = qt_invokable_token;
3723 ast->decl_specifier_list = decl_specifier_seq;
3724 ast->declarator = firstDeclarator;
3725 ast->ctor_initializer = ctor_initializer;
3726 parseFunctionBody(ast->function_body);
3728 return true; // recognized a function definition.
3729 } else if (LA() == T_TRY) {
3730 FunctionDefinitionAST *ast = new (_pool) FunctionDefinitionAST;
3731 ast->qt_invokable_token = qt_invokable_token;
3732 ast->decl_specifier_list = decl_specifier_seq;
3733 ast->declarator = firstDeclarator;
3734 ast->ctor_initializer = ctor_initializer;
3735 parseTryBlockStatement(ast->function_body);
3737 return true; // recognized a function definition.
3741 error(cursor(), "unexpected token `%s'", tok().spell());
3745 bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const
3747 // look at the decl_specifier for possible fwd or class declarations.
3748 if (SpecifierListAST *it = decl_specifier_seq) {
3750 SimpleSpecifierAST *spec = it->value->asSimpleSpecifier();
3751 if (spec && _translationUnit->tokenKind(spec->specifier_token) == T_FRIEND)
3758 SpecifierAST *spec = it->value;
3760 if (spec->asElaboratedTypeSpecifier() ||
3761 spec->asEnumSpecifier() ||
3762 spec->asClassSpecifier()) {
3763 for (it = it->next; it; it = it->next)
3764 if (it->value->asAttributeSpecifier() == 0)
3774 bool Parser::parseFunctionBody(StatementAST *&node)
3777 if (_translationUnit->skipFunctionBody()) {
3778 unsigned token_lbrace = 0;
3779 match(T_LBRACE, &token_lbrace);
3783 const Token &tk = _translationUnit->tokenAt(token_lbrace);
3785 rewind(tk.close_brace);
3786 unsigned token_rbrace = 0;
3787 match(T_RBRACE, &token_rbrace);
3791 _inFunctionBody = true;
3792 const bool parsed = parseCompoundStatement(node);
3793 _inFunctionBody = false;
3797 bool Parser::parseTryBlockStatement(StatementAST *&node)
3800 if (LA() == T_TRY) {
3801 TryBlockStatementAST *ast = new (_pool) TryBlockStatementAST;
3802 ast->try_token = consumeToken();
3803 parseCompoundStatement(ast->statement);
3804 CatchClauseListAST **catch_clause_ptr = &ast->catch_clause_list;
3805 while (parseCatchClause(*catch_clause_ptr))
3806 catch_clause_ptr = &(*catch_clause_ptr)->next;
3813 bool Parser::parseCatchClause(CatchClauseListAST *&node)
3816 if (LA() == T_CATCH) {
3817 CatchClauseAST *ast = new (_pool) CatchClauseAST;
3818 ast->catch_token = consumeToken();
3819 match(T_LPAREN, &ast->lparen_token);
3820 parseExceptionDeclaration(ast->exception_declaration);
3821 match(T_RPAREN, &ast->rparen_token);
3822 parseCompoundStatement(ast->statement);
3823 node = new (_pool) CatchClauseListAST(ast);
3829 bool Parser::parseExceptionDeclaration(ExceptionDeclarationAST *&node)
3832 if (LA() == T_DOT_DOT_DOT) {
3833 ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST;
3834 ast->dot_dot_dot_token = consumeToken();
3839 SpecifierListAST *type_specifier = 0;
3840 if (parseTypeSpecifier(type_specifier)) {
3841 ExceptionDeclarationAST *ast = new (_pool) ExceptionDeclarationAST;
3842 ast->type_specifier_list = type_specifier;
3843 parseDeclaratorOrAbstractDeclarator(ast->declarator, type_specifier);
3850 bool Parser::parseBoolLiteral(ExpressionAST *&node)
3853 if (LA() == T_TRUE || LA() == T_FALSE) {
3854 BoolLiteralAST *ast = new (_pool) BoolLiteralAST;
3855 ast->literal_token = consumeToken();
3862 bool Parser::parseNumericLiteral(ExpressionAST *&node)
3865 if (LA() == T_NUMERIC_LITERAL ||
3866 LA() == T_CHAR_LITERAL ||
3867 LA() == T_WIDE_CHAR_LITERAL) {
3868 NumericLiteralAST *ast = new (_pool) NumericLiteralAST;
3869 ast->literal_token = consumeToken();
3876 bool Parser::parseThisExpression(ExpressionAST *&node)
3879 if (LA() == T_THIS) {
3880 ThisExpressionAST *ast = new (_pool) ThisExpressionAST;
3881 ast->this_token = consumeToken();
3888 bool Parser::parsePrimaryExpression(ExpressionAST *&node)
3892 case T_STRING_LITERAL:
3893 case T_WIDE_STRING_LITERAL:
3894 return parseStringLiteral(node);
3896 case T_CHAR_LITERAL: // ### FIXME don't use NumericLiteral for chars
3897 case T_WIDE_CHAR_LITERAL:
3898 case T_NUMERIC_LITERAL:
3899 return parseNumericLiteral(node);
3903 return parseBoolLiteral(node);
3906 return parseThisExpression(node);
3909 if (LA(2) == T_LBRACE) {
3910 // GNU extension: '(' '{' statement-list '}' ')'
3911 CompoundExpressionAST *ast = new (_pool) CompoundExpressionAST;
3912 ast->lparen_token = consumeToken();
3913 StatementAST *statement = 0;
3914 parseCompoundStatement(statement);
3915 ast->statement = statement->asCompoundStatement();
3916 match(T_RPAREN, &ast->rparen_token);
3920 return parseNestedExpression(node);
3925 return parseQtMethod(node);
3928 const unsigned lbracket_token = cursor();
3930 if (_cxx0xEnabled) {
3931 if (parseLambdaExpression(node))
3936 rewind(lbracket_token);
3937 return parseObjCExpression(node);
3941 case T_AT_STRING_LITERAL:
3945 return parseObjCExpression(node);
3949 if (parseNameId(name)) {
3950 IdExpressionAST *ast = new (_pool) IdExpressionAST;
3963 bool Parser::parseObjCExpression(ExpressionAST *&node)
3968 return parseObjCEncodeExpression(node);
3971 return parseObjCProtocolExpression(node);
3974 return parseObjCSelectorExpression(node);
3977 return parseObjCMessageExpression(node);
3979 case T_AT_STRING_LITERAL:
3980 return parseObjCStringLiteral(node);
3988 bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
3991 if (LA() != T_AT_STRING_LITERAL)
3994 StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
3996 while (LA() == T_AT_STRING_LITERAL) {
3997 *ast = new (_pool) StringLiteralAST;
3998 (*ast)->literal_token = consumeToken();
3999 ast = &(*ast)->next;
4004 bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
4007 if (LA() != T_AT_SYNCHRONIZED)
4010 ObjCSynchronizedStatementAST *ast = new (_pool) ObjCSynchronizedStatementAST;
4012 ast->synchronized_token = consumeToken();
4013 match(T_LPAREN, &ast->lparen_token);
4014 parseExpression(ast->synchronized_object);
4015 match(T_RPAREN, &ast->rparen_token);
4016 parseStatement(ast->statement);
4022 bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
4025 if (LA() != T_AT_ENCODE)
4028 ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
4029 ast->encode_token = consumeToken();
4030 parseObjCTypeName(ast->type_name);
4035 bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
4038 if (LA() != T_AT_PROTOCOL)
4041 ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST;
4042 ast->protocol_token = consumeToken();
4043 match(T_LPAREN, &ast->lparen_token);
4044 match(T_IDENTIFIER, &ast->identifier_token);
4045 match(T_RPAREN, &ast->rparen_token);
4050 bool Parser::parseObjCSelectorExpression(ExpressionAST *&node)
4053 if (LA() != T_AT_SELECTOR)
4056 ObjCSelectorExpressionAST *ast = new (_pool) ObjCSelectorExpressionAST;
4057 ast->selector_token = consumeToken();
4058 match(T_LPAREN, &ast->lparen_token);
4060 unsigned identifier_token = 0;
4061 match(T_IDENTIFIER, &identifier_token);
4062 if (LA() == T_COLON) {
4063 ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
4064 ast->selector = args;
4065 ObjCSelectorArgumentListAST *last = new (_pool) ObjCSelectorArgumentListAST;
4066 args->selector_argument_list = last;
4067 last->value = new (_pool) ObjCSelectorArgumentAST;
4068 last->value->name_token = identifier_token;
4069 last->value->colon_token = consumeToken();
4071 while (LA(1) == T_IDENTIFIER && LA(2) == T_COLON) {
4072 last->next = new (_pool) ObjCSelectorArgumentListAST;
4074 last->value = new (_pool) ObjCSelectorArgumentAST;
4075 last->value->name_token = consumeToken();
4076 last->value->colon_token = consumeToken();
4079 ObjCSelectorAST *args = new (_pool) ObjCSelectorAST;
4080 ast->selector = args;
4081 args->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
4082 args->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
4083 args->selector_argument_list->value->name_token = identifier_token;
4086 if (LA(1) == T_IDENTIFIER && LA(2) == T_RPAREN) {
4087 const char *txt = tok(1).spell();
4089 error(cursor(), "missing ':' after '%s'", txt);
4091 match(T_RPAREN, &ast->rparen_token);
4097 bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
4100 if (LA() != T_LBRACKET)
4103 unsigned start = cursor();
4105 unsigned lbracket_token = consumeToken();
4106 ExpressionAST *receiver_expression = 0;
4107 ObjCSelectorAST *selector = 0;
4108 ObjCMessageArgumentListAST *argument_list = 0;
4110 if (parseObjCMessageReceiver(receiver_expression) &&
4111 parseObjCMessageArguments(selector, argument_list)) {
4113 ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
4114 ast->lbracket_token = lbracket_token;
4115 ast->receiver_expression = receiver_expression;
4116 ast->selector = selector;
4117 ast->argument_list = argument_list;
4119 match(T_RBRACKET, &ast->rbracket_token);
4129 bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
4132 return parseExpression(node);
4135 bool Parser::parseObjCMessageArguments(ObjCSelectorAST *&selNode, ObjCMessageArgumentListAST *& argNode)
4138 if (LA() == T_RBRACKET)
4139 return false; // nothing to do.
4141 unsigned start = cursor();
4143 ObjCSelectorArgumentAST *selectorArgument = 0;
4144 ObjCMessageArgumentAST *messageArgument = 0;
4146 if (parseObjCSelectorArg(selectorArgument, messageArgument)) {
4147 ObjCSelectorArgumentListAST *selAst = new (_pool) ObjCSelectorArgumentListAST;
4148 selAst->value = selectorArgument;
4149 ObjCSelectorArgumentListAST *lastSelector = selAst;
4151 ObjCMessageArgumentListAST *argAst = new (_pool) ObjCMessageArgumentListAST;
4152 argAst->value = messageArgument;
4153 ObjCMessageArgumentListAST *lastArgument = argAst;
4155 while (parseObjCSelectorArg(selectorArgument, messageArgument)) {
4156 // accept the selector args.
4157 lastSelector->next = new (_pool) ObjCSelectorArgumentListAST;
4158 lastSelector = lastSelector->next;
4159 lastSelector->value = selectorArgument;
4161 lastArgument->next = new (_pool) ObjCMessageArgumentListAST;
4162 lastArgument = lastArgument->next;
4163 lastArgument->value = messageArgument;
4166 if (LA() == T_COMMA) {
4167 ExpressionAST **lastExpression = &lastArgument->value->parameter_value_expression;
4169 while (LA() == T_COMMA) {
4170 BinaryExpressionAST *binaryExpression = new (_pool) BinaryExpressionAST;
4171 binaryExpression->left_expression = *lastExpression;
4172 binaryExpression->binary_op_token = consumeToken(); // T_COMMA
4173 parseAssignmentExpression(binaryExpression->right_expression);
4174 lastExpression = &binaryExpression->right_expression;
4178 ObjCSelectorAST *selWithArgs = new (_pool) ObjCSelectorAST;
4179 selWithArgs->selector_argument_list = selAst;
4181 selNode = selWithArgs;
4186 unsigned name_token = 0;
4187 if (!parseObjCSelector(name_token))
4189 ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
4190 sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
4191 sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
4192 sel->selector_argument_list->value->name_token = name_token;
4201 bool Parser::parseObjCSelectorArg(ObjCSelectorArgumentAST *&selNode, ObjCMessageArgumentAST *&argNode)
4204 unsigned selector_token = 0;
4205 if (!parseObjCSelector(selector_token))
4208 if (LA() != T_COLON)
4211 selNode = new (_pool) ObjCSelectorArgumentAST;
4212 selNode->name_token = selector_token;
4213 selNode->colon_token = consumeToken();
4215 argNode = new (_pool) ObjCMessageArgumentAST;
4216 ExpressionAST **expr = &argNode->parameter_value_expression;
4217 unsigned expressionStart = cursor();
4218 if (parseAssignmentExpression(*expr) && LA() == T_COLON && (*expr)->asCastExpression()) {
4219 rewind(expressionStart);
4220 parseUnaryExpression(*expr);
4226 bool Parser::parseNameId(NameAST *&name)
4229 unsigned start = cursor();
4230 if (! parseName(name))
4233 if (LA() == T_RPAREN || LA() == T_COMMA)
4236 QualifiedNameAST *qualified_name_id = name->asQualifiedName();
4238 TemplateIdAST *template_id = 0;
4239 if (qualified_name_id) {
4240 if (NameAST *unqualified_name = qualified_name_id->unqualified_name)
4241 template_id = unqualified_name->asTemplateId();
4243 template_id = name->asTemplateId();
4247 return true; // it's not a template-id, there's nothing to rewind.
4249 else if (LA() == T_LPAREN) {
4250 // a template-id followed by a T_LPAREN
4251 if (ExpressionListAST *template_arguments = template_id->template_argument_list) {
4252 if (! template_arguments->next && template_arguments->value &&
4253 template_arguments->value->asBinaryExpression()) {
4255 unsigned saved = cursor();
4256 ExpressionAST *expr = 0;
4258 bool blocked = blockErrors(true);
4259 bool lookAtCastExpression = parseCastExpression(expr);
4260 (void) blockErrors(blocked);
4262 if (lookAtCastExpression) {
4263 if (CastExpressionAST *cast_expression = expr->asCastExpression()) {
4264 if (cast_expression->lparen_token && cast_expression->rparen_token
4265 && cast_expression->type_id && cast_expression->expression) {
4269 return parseName(name, false);
4287 case T_DYNAMIC_CAST:
4288 case T_REINTERPRET_CAST:
4291 return parseName(name, false);
4294 if (tok().isLiteral() || tok().isOperator()) {
4296 return parseName(name, false);
4303 bool Parser::parseNestedExpression(ExpressionAST *&node)
4306 if (LA() == T_LPAREN) {
4307 unsigned lparen_token = consumeToken();
4308 bool previousTemplateArguments = switchTemplateArguments(false);
4310 ExpressionAST *expression = 0;
4311 if (parseExpression(expression) && LA() == T_RPAREN) {
4312 NestedExpressionAST *ast = new (_pool) NestedExpressionAST;
4313 ast->lparen_token = lparen_token;
4314 ast->expression = expression;
4315 ast->rparen_token = consumeToken();
4317 (void) switchTemplateArguments(previousTemplateArguments);
4320 (void) switchTemplateArguments(previousTemplateArguments);
4325 bool Parser::parseCppCastExpression(ExpressionAST *&node)
4328 if (LA() == T_DYNAMIC_CAST || LA() == T_STATIC_CAST ||
4329 LA() == T_REINTERPRET_CAST || LA() == T_CONST_CAST) {
4330 CppCastExpressionAST *ast = new (_pool) CppCastExpressionAST;
4331 ast->cast_token = consumeToken();
4332 match(T_LESS, &ast->less_token);
4333 parseTypeId(ast->type_id);
4334 match(T_GREATER, &ast->greater_token);
4335 match(T_LPAREN, &ast->lparen_token);
4336 parseExpression(ast->expression);
4337 match(T_RPAREN, &ast->rparen_token);
4344 // typename ::opt nested-name-specifier identifier ( expression-listopt )
4345 // typename ::opt nested-name-specifier templateopt template-id ( expression-listopt )
4346 bool Parser::parseTypenameCallExpression(ExpressionAST *&node)
4349 if (LA() == T_TYPENAME) {
4350 unsigned typename_token = consumeToken();
4352 if (parseName(name) && LA() == T_LPAREN) {
4353 TypenameCallExpressionAST *ast = new (_pool) TypenameCallExpressionAST;
4354 ast->typename_token = typename_token;
4356 ast->lparen_token = consumeToken();
4357 parseExpressionList(ast->expression_list);
4358 match(T_RPAREN, &ast->rparen_token);
4366 // typeid ( expression )
4367 // typeid ( type-id )
4368 bool Parser::parseTypeidExpression(ExpressionAST *&node)
4371 if (LA() == T_TYPEID) {
4372 TypeidExpressionAST *ast = new (_pool) TypeidExpressionAST;
4373 ast->typeid_token = consumeToken();
4374 if (LA() == T_LPAREN)
4375 ast->lparen_token = consumeToken();
4376 unsigned saved = cursor();
4377 if (! (parseTypeId(ast->expression) && LA() == T_RPAREN)) {
4379 parseExpression(ast->expression);
4381 match(T_RPAREN, &ast->rparen_token);
4388 bool Parser::parseCorePostfixExpression(ExpressionAST *&node)
4393 case T_DYNAMIC_CAST:
4395 case T_REINTERPRET_CAST:
4397 return parseCppCastExpression(node);
4400 return parseTypenameCallExpression(node);
4403 return parseTypeidExpression(node);
4406 unsigned start = cursor();
4407 SpecifierListAST *type_specifier = 0;
4408 bool blocked = blockErrors(true);
4409 if (lookAtBuiltinTypeSpecifier() &&
4410 parseSimpleTypeSpecifier(type_specifier) &&
4412 unsigned lparen_token = consumeToken();
4413 ExpressionListAST *expression_list = 0;
4414 parseExpressionList(expression_list);
4415 if (LA() == T_RPAREN) {
4416 unsigned rparen_token = consumeToken();
4417 TypeConstructorCallAST *ast = new (_pool) TypeConstructorCallAST;
4418 ast->type_specifier_list = type_specifier;
4419 ast->lparen_token = lparen_token;
4420 ast->expression_list = expression_list;
4421 ast->rparen_token = rparen_token;
4423 blockErrors(blocked);
4429 // look for compound literals
4430 if (LA() == T_LPAREN) {
4431 unsigned lparen_token = consumeToken();
4432 ExpressionAST *type_id = 0;
4433 if (parseTypeId(type_id) && LA() == T_RPAREN) {
4434 unsigned rparen_token = consumeToken();
4435 if (LA() == T_LBRACE) {
4436 blockErrors(blocked);
4438 CompoundLiteralAST *ast = new (_pool) CompoundLiteralAST;
4439 ast->lparen_token = lparen_token;
4440 ast->type_id = type_id;
4441 ast->rparen_token = rparen_token;
4442 parseInitializerClause(ast->initializer);
4450 blockErrors(blocked);
4451 return parsePrimaryExpression(node);
4456 bool Parser::parsePostfixExpression(ExpressionAST *&node)
4459 if (parseCorePostfixExpression(node)) {
4461 if (LA() == T_LPAREN) {
4462 CallAST *ast = new (_pool) CallAST;
4463 ast->lparen_token = consumeToken();
4464 parseExpressionList(ast->expression_list);
4465 match(T_RPAREN, &ast->rparen_token);
4466 ast->base_expression = node;
4468 } else if (LA() == T_LBRACKET) {
4469 ArrayAccessAST *ast = new (_pool) ArrayAccessAST;
4470 ast->lbracket_token = consumeToken();
4471 parseExpression(ast->expression);
4472 match(T_RBRACKET, &ast->rbracket_token);
4473 ast->base_expression = node;
4475 } else if (LA() == T_PLUS_PLUS || LA() == T_MINUS_MINUS) {
4476 PostIncrDecrAST *ast = new (_pool) PostIncrDecrAST;
4477 ast->incr_decr_token = consumeToken();
4478 ast->base_expression = node;
4480 } else if (LA() == T_DOT || LA() == T_ARROW) {
4481 MemberAccessAST *ast = new (_pool) MemberAccessAST;
4482 ast->access_token = consumeToken();
4483 if (LA() == T_TEMPLATE)
4484 ast->template_token = consumeToken();
4485 if (! parseNameId(ast->member_name))
4486 error(cursor(), "expected unqualified-id before token `%s'",
4488 ast->base_expression = node;
4498 bool Parser::parseUnaryExpression(ExpressionAST *&node)
4509 unsigned op = cursor();
4510 UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST;
4511 ast->unary_op_token = consumeToken();
4512 if (! parseCastExpression(ast->expression)) {
4513 error(op, "expected expression after token `%s'",
4514 _translationUnit->spell(op));
4521 if (LA(2) == T_IDENTIFIER && LA(3) == T_LPAREN)
4522 break; // prefer destructor names
4524 UnaryExpressionAST *ast = new (_pool) UnaryExpressionAST;
4525 ast->unary_op_token = consumeToken();
4526 (void) parseCastExpression(ast->expression);
4532 SizeofExpressionAST *ast = new (_pool) SizeofExpressionAST;
4533 ast->sizeof_token = consumeToken();
4536 if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_IDENTIFIER || (LA(2) == T_LPAREN && LA(3) == T_IDENTIFIER
4537 && LA(4) == T_RPAREN)))
4538 ast->dot_dot_dot_token = consumeToken();
4540 if (LA() == T_LPAREN) {
4541 unsigned lparen_token = consumeToken();
4542 const bool blocked = blockErrors(true);
4543 const bool hasTypeId = parseTypeId(ast->expression);
4544 (void) blockErrors(blocked);
4545 if (hasTypeId && LA() == T_RPAREN) {
4546 ast->lparen_token = lparen_token;
4547 ast->rparen_token = consumeToken();
4551 rewind(lparen_token);
4555 parseUnaryExpression(ast->expression);
4565 if (LA() == T_NEW || (LA(1) == T_COLON_COLON &&
4567 return parseNewExpression(node);
4568 else if (LA() == T_DELETE || (LA(1) == T_COLON_COLON &&
4570 return parseDeleteExpression(node);
4572 return parsePostfixExpression(node);
4575 // new-placement ::= T_LPAREN expression-list T_RPAREN
4576 bool Parser::parseNewPlacement(NewPlacementAST *&node)
4579 if (LA() == T_LPAREN) {
4580 unsigned lparen_token = consumeToken();
4581 ExpressionListAST *expression_list = 0;
4582 if (parseExpressionList(expression_list) && expression_list && LA() == T_RPAREN) {
4583 unsigned rparen_token = consumeToken();
4584 NewPlacementAST *ast = new (_pool) NewPlacementAST;
4585 ast->lparen_token = lparen_token;
4586 ast->expression_list = expression_list;
4587 ast->rparen_token = rparen_token;
4596 // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
4597 // new-type-id new-initializer.opt
4598 // new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
4599 // T_LPAREN type-id T_RPAREN new-initializer.opt
4600 bool Parser::parseNewExpression(ExpressionAST *&node)
4603 if (! (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)))
4606 NewExpressionAST *ast = new (_pool) NewExpressionAST;
4607 if (LA() == T_COLON_COLON)
4608 ast->scope_token = consumeToken();
4610 ast->new_token = consumeToken();
4612 NewPlacementAST *new_placement = 0;
4614 if (parseNewPlacement(new_placement)) {
4615 unsigned after_new_placement = cursor();
4617 NewTypeIdAST *new_type_id = 0;
4618 if (parseNewTypeId(new_type_id)) {
4619 ast->new_placement = new_placement;
4620 ast->new_type_id = new_type_id;
4621 parseNewInitializer(ast->new_initializer);
4622 // recognized new-placement.opt new-type-id new-initializer.opt
4627 rewind(after_new_placement);
4628 if (LA() == T_LPAREN) {
4629 unsigned lparen_token = consumeToken();
4630 ExpressionAST *type_id = 0;
4631 if (parseTypeId(type_id) && LA() == T_RPAREN) {
4632 ast->new_placement = new_placement;
4633 ast->lparen_token = lparen_token;
4634 ast->type_id = type_id;
4635 ast->rparen_token = consumeToken();
4636 parseNewInitializer(ast->new_initializer);
4643 rewind(ast->new_token + 1);
4645 if (LA() == T_LPAREN) {
4646 unsigned lparen_token = consumeToken();
4647 ExpressionAST *type_id = 0;
4648 if (parseTypeId(type_id) && LA() == T_RPAREN) {
4649 ast->lparen_token = lparen_token;
4650 ast->type_id = type_id;
4651 ast->rparen_token = consumeToken();
4652 parseNewInitializer(ast->new_initializer);
4658 parseNewTypeId(ast->new_type_id);
4659 parseNewInitializer(ast->new_initializer);
4664 bool Parser::parseNewTypeId(NewTypeIdAST *&node)
4667 SpecifierListAST *typeSpec = 0;
4668 if (! parseTypeSpecifier(typeSpec))
4671 NewTypeIdAST *ast = new (_pool) NewTypeIdAST;
4672 ast->type_specifier_list = typeSpec;
4674 PtrOperatorListAST **ptrop_it = &ast->ptr_operator_list;
4675 while (parsePtrOperator(*ptrop_it))
4676 ptrop_it = &(*ptrop_it)->next;
4678 NewArrayDeclaratorListAST **it = &ast->new_array_declarator_list;
4679 while (parseNewArrayDeclarator(*it))
4687 bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorListAST *&node)
4690 if (LA() != T_LBRACKET)
4693 NewArrayDeclaratorAST *ast = new (_pool) NewArrayDeclaratorAST;
4694 ast->lbracket_token = consumeToken();
4695 parseExpression(ast->expression);
4696 match(T_RBRACKET, &ast->rbracket_token);
4698 node = new (_pool) NewArrayDeclaratorListAST;
4703 bool Parser::parseNewInitializer(NewInitializerAST *&node)
4706 if (LA() == T_LPAREN) {
4707 unsigned lparen_token = consumeToken();
4708 ExpressionAST *expression = 0;
4709 if (LA() == T_RPAREN || parseExpression(expression)) {
4710 NewInitializerAST *ast = new (_pool) NewInitializerAST;
4711 ast->lparen_token = lparen_token;
4712 ast->expression = expression;
4713 match(T_RPAREN, &ast->rparen_token);
4721 bool Parser::parseDeleteExpression(ExpressionAST *&node)
4724 if (LA() == T_DELETE || (LA() == T_COLON_COLON && LA(2) == T_DELETE)) {
4725 DeleteExpressionAST *ast = new (_pool) DeleteExpressionAST;
4727 if (LA() == T_COLON_COLON)
4728 ast->scope_token = consumeToken();
4730 ast->delete_token = consumeToken();
4732 if (LA() == T_LBRACKET) {
4733 ast->lbracket_token = consumeToken();
4734 match(T_RBRACKET, &ast->rbracket_token);
4737 (void) parseCastExpression(ast->expression);
4744 bool Parser::parseCastExpression(ExpressionAST *&node)
4747 if (LA() == T_LPAREN) {
4748 unsigned lparen_token = consumeToken();
4749 ExpressionAST *type_id = 0;
4750 if (parseTypeId(type_id) && LA() == T_RPAREN) {
4752 if (TypeIdAST *tid = type_id->asTypeId()) {
4753 if (tid->type_specifier_list && ! tid->type_specifier_list->next) {
4754 if (tid->type_specifier_list->value->asNamedTypeSpecifier()) {
4756 case T_LBRACKET: // ... it's definitely a unary expression followed by an array access.
4757 goto parse_as_unary_expression;
4760 case T_MINUS_MINUS: {
4761 const unsigned rparen_token = consumeToken();
4763 const bool blocked = blockErrors(true);
4764 ExpressionAST *unary = 0;
4765 bool followedByUnaryExpression = parseUnaryExpression(unary);
4766 blockErrors(blocked);
4767 rewind(rparen_token);
4769 if (followedByUnaryExpression) {
4771 followedByUnaryExpression = false;
4772 else if (UnaryExpressionAST *u = unary->asUnaryExpression())
4773 followedByUnaryExpression = u->expression != 0;
4776 if (! followedByUnaryExpression)
4777 goto parse_as_unary_expression;
4781 case T_LPAREN: // .. it can be parsed as a function call.
4782 // ### TODO: check if it is followed by a parenthesized expression list.
4789 unsigned rparen_token = consumeToken();
4790 ExpressionAST *expression = 0;
4791 if (parseCastExpression(expression)) {
4792 CastExpressionAST *ast = new (_pool) CastExpressionAST;
4793 ast->lparen_token = lparen_token;
4794 ast->type_id = type_id;
4795 ast->rparen_token = rparen_token;
4796 ast->expression = expression;
4802 parse_as_unary_expression:
4803 rewind(lparen_token);
4806 return parseUnaryExpression(node);
4809 bool Parser::parsePmExpression(ExpressionAST *&node)
4811 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::PointerToMember)
4814 bool Parser::parseMultiplicativeExpression(ExpressionAST *&node)
4816 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Multiplicative)
4819 bool Parser::parseAdditiveExpression(ExpressionAST *&node)
4821 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Additive)
4824 bool Parser::parseShiftExpression(ExpressionAST *&node)
4826 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Shift)
4829 bool Parser::parseRelationalExpression(ExpressionAST *&node)
4831 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Relational)
4834 bool Parser::parseEqualityExpression(ExpressionAST *&node)
4836 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Equality)
4839 bool Parser::parseAndExpression(ExpressionAST *&node)
4841 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::And)
4844 bool Parser::parseExclusiveOrExpression(ExpressionAST *&node)
4846 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::ExclusiveOr)
4849 bool Parser::parseInclusiveOrExpression(ExpressionAST *&node)
4851 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::InclusiveOr)
4854 bool Parser::parseLogicalAndExpression(ExpressionAST *&node)
4856 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::LogicalAnd)
4859 bool Parser::parseLogicalOrExpression(ExpressionAST *&node)
4861 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::LogicalOr)
4864 bool Parser::parseConditionalExpression(ExpressionAST *&node)
4866 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Conditional)
4869 bool Parser::parseAssignmentExpression(ExpressionAST *&node)
4872 if (LA() == T_THROW)
4873 return parseThrowExpression(node);
4875 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Assignment)
4878 bool Parser::parseQtMethod(ExpressionAST *&node)
4881 if (LA() == T_SIGNAL || LA() == T_SLOT) {
4882 QtMethodAST *ast = new (_pool) QtMethodAST;
4883 ast->method_token = consumeToken();
4884 match(T_LPAREN, &ast->lparen_token);
4885 if (! parseDeclarator(ast->declarator, /*decl_specifier_seq =*/ 0))
4886 error(cursor(), "expected a function declarator before token `%s'",
4888 match(T_RPAREN, &ast->rparen_token);
4895 bool Parser::parseConstantExpression(ExpressionAST *&node)
4898 return parseConditionalExpression(node);
4901 bool Parser::parseExpression(ExpressionAST *&node)
4905 if (_expressionDepth > MAX_EXPRESSION_DEPTH)
4909 bool success = parseCommaExpression(node);
4914 void Parser::parseExpressionWithOperatorPrecedence(ExpressionAST *&lhs, int minPrecedence)
4918 while (precedence(tok().kind(), _templateArguments) >= minPrecedence) {
4919 const int operPrecedence = precedence(tok().kind(), _templateArguments);
4920 const int oper = consumeToken();
4922 ConditionalExpressionAST *condExpr = 0;
4923 if (operPrecedence == Prec::Conditional) {
4924 condExpr = new (_pool) ConditionalExpressionAST;
4925 condExpr->question_token = oper;
4926 if (tok().kind() == T_COLON) {
4928 // logical-or-expression '?' ':' conditional-expression
4929 condExpr->left_expression = 0;
4931 parseExpression(condExpr->left_expression);
4933 match(T_COLON, &condExpr->colon_token);
4936 ExpressionAST *rhs = 0;
4937 const bool isCPlusPlus = true;
4938 if (operPrecedence <= Prec::Conditional && isCPlusPlus) {
4939 // in C++ you can put a throw in the right-most expression of a conditional expression,
4940 // or an assignment, so some special handling:
4941 if (!parseAssignmentExpression(rhs))
4944 // for C & all other expressions:
4945 if (!parseCastExpression(rhs))
4949 for (int tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments);
4950 (precedenceAhead > operPrecedence && isBinaryOperator(tokenKindAhead))
4951 || (precedenceAhead == operPrecedence && isRightAssociative(tokenKindAhead));
4952 tokenKindAhead = tok().kind(), precedenceAhead = precedence(tokenKindAhead, _templateArguments)) {
4953 parseExpressionWithOperatorPrecedence(rhs, precedenceAhead);
4956 if (condExpr) { // we were parsing a ternairy conditional expression
4957 condExpr->condition = lhs;
4958 condExpr->right_expression = rhs;
4961 BinaryExpressionAST *expr = new (_pool) BinaryExpressionAST;
4962 expr->left_expression = lhs;
4963 expr->binary_op_token = oper;
4964 expr->right_expression = rhs;
4970 bool Parser::parseCommaExpression(ExpressionAST *&node)
4972 PARSE_EXPRESSION_WITH_OPERATOR_PRECEDENCE(node, Prec::Comma)
4975 bool Parser::parseThrowExpression(ExpressionAST *&node)
4978 if (LA() == T_THROW) {
4979 ThrowExpressionAST *ast = new (_pool) ThrowExpressionAST;
4980 ast->throw_token = consumeToken();
4981 parseAssignmentExpression(ast->expression);
4988 bool Parser::lookAtObjCSelector() const
5006 if (tok().isKeyword())
5013 // objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
5015 bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
5018 if (LA() != T_AT_CLASS)
5021 ObjCClassForwardDeclarationAST *ast = new (_pool) ObjCClassForwardDeclarationAST;
5023 ast->class_token = consumeToken();
5024 unsigned identifier_token = 0;
5025 match(T_IDENTIFIER, &identifier_token);
5027 ast->identifier_list = new (_pool) NameListAST;
5028 SimpleNameAST *name = new (_pool) SimpleNameAST;
5029 name->identifier_token = identifier_token;
5030 ast->identifier_list->value = name;
5031 NameListAST **nextId = &ast->identifier_list->next;
5033 while (LA() == T_COMMA) {
5034 consumeToken(); // consume T_COMMA
5035 match(T_IDENTIFIER, &identifier_token);
5037 *nextId = new (_pool) NameListAST;
5038 name = new (_pool) SimpleNameAST;
5039 name->identifier_token = identifier_token;
5040 (*nextId)->value = name;
5041 nextId = &(*nextId)->next;
5044 match(T_SEMICOLON, &ast->semicolon_token);
5049 // objc-interface ::= attribute-specifier-list-opt objc-class-interface
5050 // objc-interface ::= objc-category-interface
5052 // objc-class-interface ::= T_AT_INTERFACE T_IDENTIFIER (T_COLON T_IDENTIFIER)?
5053 // objc-protocol-refs-opt
5054 // objc-class-instance-variables-opt
5055 // objc-interface-declaration-list
5058 // objc-category-interface ::= T_AT_INTERFACE T_IDENTIFIER
5059 // T_LPAREN T_IDENTIFIER? T_RPAREN
5060 // objc-protocol-refs-opt
5061 // objc-interface-declaration-list
5064 bool Parser::parseObjCInterface(DeclarationAST *&node,
5065 SpecifierListAST *attributes)
5068 if (! attributes && LA() == T___ATTRIBUTE__) {
5069 SpecifierListAST **attr = &attributes;
5070 while (parseAttributeSpecifier(*attr))
5071 attr = &(*attr)->next;
5074 if (LA() != T_AT_INTERFACE)
5077 unsigned objc_interface_token = consumeToken();
5078 unsigned identifier_token = 0;
5079 match(T_IDENTIFIER, &identifier_token);
5081 if (LA() == T_LPAREN) {
5082 // a category interface
5085 error(attributes->firstToken(),
5086 "invalid attributes for category interface declaration");
5088 ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
5089 ast->attribute_list = attributes;
5090 ast->interface_token = objc_interface_token;
5091 SimpleNameAST *class_name = new (_pool) SimpleNameAST;
5092 class_name->identifier_token= identifier_token;
5093 ast->class_name = class_name;
5095 match(T_LPAREN, &ast->lparen_token);
5096 if (LA() == T_IDENTIFIER) {
5097 SimpleNameAST *category_name = new (_pool) SimpleNameAST;
5098 category_name->identifier_token = consumeToken();
5099 ast->category_name = category_name;
5102 match(T_RPAREN, &ast->rparen_token);
5104 parseObjCProtocolRefs(ast->protocol_refs);
5106 DeclarationListAST **nextMembers = &ast->member_declaration_list;
5107 DeclarationAST *declaration = 0;
5108 while (parseObjCInterfaceMemberDeclaration(declaration)) {
5109 *nextMembers = new (_pool) DeclarationListAST;
5110 (*nextMembers)->value = declaration;
5111 nextMembers = &(*nextMembers)->next;
5114 match(T_AT_END, &ast->end_token);
5119 // a class interface declaration
5120 ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
5121 ast->attribute_list = attributes;
5122 ast->interface_token = objc_interface_token;
5123 SimpleNameAST* class_name = new (_pool) SimpleNameAST;
5124 class_name->identifier_token = identifier_token;
5125 ast->class_name = class_name;
5127 if (LA() == T_COLON) {
5128 ast->colon_token = consumeToken();
5129 SimpleNameAST *superclass = new (_pool) SimpleNameAST;
5130 match(T_IDENTIFIER, &superclass->identifier_token);
5131 ast->superclass = superclass;
5134 parseObjCProtocolRefs(ast->protocol_refs);
5135 parseObjClassInstanceVariables(ast->inst_vars_decl);
5137 DeclarationListAST **nextMembers = &ast->member_declaration_list;
5138 DeclarationAST *declaration = 0;
5139 while (parseObjCInterfaceMemberDeclaration(declaration)) {
5140 *nextMembers = new (_pool) DeclarationListAST;
5141 (*nextMembers)->value = declaration;
5142 nextMembers = &(*nextMembers)->next;
5145 match(T_AT_END, &ast->end_token);
5152 // objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
5154 bool Parser::parseObjCProtocol(DeclarationAST *&node,
5155 SpecifierListAST *attributes)
5158 if (! attributes && LA() == T___ATTRIBUTE__) {
5159 SpecifierListAST **attr = &attributes;
5160 while (parseAttributeSpecifier(*attr))
5161 attr = &(*attr)->next;
5164 if (LA() != T_AT_PROTOCOL)
5167 unsigned protocol_token = consumeToken();
5168 unsigned identifier_token = 0;
5169 match(T_IDENTIFIER, &identifier_token);
5171 if (LA() == T_COMMA || LA() == T_SEMICOLON) {
5172 // a protocol forward declaration
5174 ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
5175 ast->attribute_list = attributes;
5176 ast->protocol_token = protocol_token;
5177 ast->identifier_list = new (_pool) NameListAST;
5178 SimpleNameAST *name = new (_pool) SimpleNameAST;
5179 name->identifier_token = identifier_token;
5180 ast->identifier_list->value = name;
5181 NameListAST **nextId = &ast->identifier_list->next;
5183 while (LA() == T_COMMA) {
5184 consumeToken(); // consume T_COMMA
5185 match(T_IDENTIFIER, &identifier_token);
5187 *nextId = new (_pool) NameListAST;
5188 name = new (_pool) SimpleNameAST;
5189 name->identifier_token = identifier_token;
5190 (*nextId)->value = name;
5191 nextId = &(*nextId)->next;
5194 match(T_SEMICOLON, &ast->semicolon_token);
5198 // a protocol definition
5199 ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
5200 ast->attribute_list = attributes;
5201 ast->protocol_token = protocol_token;
5202 SimpleNameAST *name = new (_pool) SimpleNameAST;
5203 name->identifier_token = identifier_token;
5206 parseObjCProtocolRefs(ast->protocol_refs);
5208 DeclarationListAST **nextMembers = &ast->member_declaration_list;
5209 DeclarationAST *declaration = 0;
5210 while (parseObjCInterfaceMemberDeclaration(declaration)) {
5211 *nextMembers = new (_pool) DeclarationListAST;
5212 (*nextMembers)->value = declaration;
5213 nextMembers = &(*nextMembers)->next;
5216 match(T_AT_END, &ast->end_token);
5223 // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER (T_COLON T_IDENTIFIER)?
5224 // objc-class-instance-variables-opt
5225 // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER T_LPAREN T_IDENTIFIER T_RPAREN
5227 bool Parser::parseObjCImplementation(DeclarationAST *&node)
5230 if (LA() != T_AT_IMPLEMENTATION)
5233 unsigned implementation_token = consumeToken();
5234 unsigned identifier_token = 0;
5235 match(T_IDENTIFIER, &identifier_token);
5237 if (LA() == T_LPAREN) {
5238 // a category implementation
5239 ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
5240 ast->implementation_token = implementation_token;
5241 SimpleNameAST *class_name = new (_pool) SimpleNameAST;
5242 class_name->identifier_token = identifier_token;
5243 ast->class_name = class_name;
5245 match(T_LPAREN, &ast->lparen_token);
5246 SimpleNameAST *category_name = new (_pool) SimpleNameAST;
5247 match(T_IDENTIFIER, &category_name->identifier_token);
5248 ast->category_name = category_name;
5249 match(T_RPAREN, &ast->rparen_token);
5251 parseObjCMethodDefinitionList(ast->member_declaration_list);
5252 match(T_AT_END, &ast->end_token);
5256 // a class implementation
5257 ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
5258 ast->implementation_token = implementation_token;
5259 SimpleNameAST *class_name = new (_pool) SimpleNameAST;
5260 class_name->identifier_token = identifier_token;
5261 ast->class_name = class_name;
5263 if (LA() == T_COLON) {
5264 ast->colon_token = consumeToken();
5265 SimpleNameAST *superclass = new (_pool) SimpleNameAST;
5266 match(T_IDENTIFIER, &superclass->identifier_token);
5267 ast->superclass = superclass;
5270 parseObjClassInstanceVariables(ast->inst_vars_decl);
5271 parseObjCMethodDefinitionList(ast->member_declaration_list);
5272 match(T_AT_END, &ast->end_token);
5280 bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
5283 DeclarationListAST **next = &node;
5285 while (LA() && LA() != T_AT_END) {
5286 unsigned start = cursor();
5287 DeclarationAST *declaration = 0;
5292 parseObjCMethodDefinition(declaration);
5294 if (start == cursor())
5302 case T_AT_SYNTHESIZE: {
5303 ObjCSynthesizedPropertiesDeclarationAST *ast = new (_pool) ObjCSynthesizedPropertiesDeclarationAST;
5304 ast->synthesized_token = consumeToken();
5305 ObjCSynthesizedPropertyListAST *last = new (_pool) ObjCSynthesizedPropertyListAST;
5306 ast->property_identifier_list = last;
5307 last->value = new (_pool) ObjCSynthesizedPropertyAST;
5308 match(T_IDENTIFIER, &last->value->property_identifier_token);
5310 if (LA() == T_EQUAL) {
5311 last->value->equals_token = consumeToken();
5313 match(T_IDENTIFIER, &last->value->alias_identifier_token);
5316 while (LA() == T_COMMA) {
5317 consumeToken(); // consume T_COMMA
5319 last->next = new (_pool) ObjCSynthesizedPropertyListAST;
5322 last->value = new (_pool) ObjCSynthesizedPropertyAST;
5323 match(T_IDENTIFIER, &last->value->property_identifier_token);
5325 if (LA() == T_EQUAL) {
5326 last->value->equals_token = consumeToken();
5328 match(T_IDENTIFIER, &last->value->alias_identifier_token);
5332 match(T_SEMICOLON, &ast->semicolon_token);
5338 case T_AT_DYNAMIC: {
5339 ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
5340 ast->dynamic_token = consumeToken();
5341 ast->property_identifier_list = new (_pool) NameListAST;
5342 SimpleNameAST *name = new (_pool) SimpleNameAST;
5343 match(T_IDENTIFIER, &name->identifier_token);
5344 ast->property_identifier_list->value = name;
5346 NameListAST *last = ast->property_identifier_list;
5347 while (LA() == T_COMMA) {
5348 consumeToken(); // consume T_COMMA
5350 last->next = new (_pool) NameListAST;
5352 name = new (_pool) SimpleNameAST;
5353 match(T_IDENTIFIER, &name->identifier_token);
5357 match(T_SEMICOLON, &ast->semicolon_token);
5364 if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL) {
5365 parseDeclaration(declaration);
5367 if (! parseBlockDeclaration(declaration)) {
5370 "skip token `%s'", tok().spell());
5379 *next = new (_pool) DeclarationListAST;
5380 (*next)->value = declaration;
5381 next = &(*next)->next;
5388 bool Parser::parseObjCMethodDefinition(DeclarationAST *&node)
5391 ObjCMethodPrototypeAST *method_prototype = 0;
5392 if (! parseObjCMethodPrototype(method_prototype))
5395 ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
5396 ast->method_prototype = method_prototype;
5398 // Objective-C allows you to write:
5399 // - (void) foo; { body; }
5400 // so a method is a forward declaration when it doesn't have a _body_.
5401 // However, we still need to read the semicolon.
5402 if (LA() == T_SEMICOLON) {
5403 ast->semicolon_token = consumeToken();
5406 parseFunctionBody(ast->function_body);
5412 // objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
5414 bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
5420 ObjCProtocolRefsAST *ast = new (_pool) ObjCProtocolRefsAST;
5422 match(T_LESS, &ast->less_token);
5424 unsigned identifier_token = 0;
5425 match(T_IDENTIFIER, &identifier_token);
5426 ast->identifier_list = new (_pool) NameListAST;
5427 SimpleNameAST *name = new (_pool) SimpleNameAST;
5428 name->identifier_token = identifier_token;
5429 ast->identifier_list->value = name;
5430 NameListAST **nextId = &ast->identifier_list->next;
5432 while (LA() == T_COMMA) {
5433 consumeToken(); // consume T_COMMA
5434 match(T_IDENTIFIER, &identifier_token);
5436 *nextId = new (_pool) NameListAST;
5437 name = new (_pool) SimpleNameAST;
5438 name->identifier_token = identifier_token;
5439 (*nextId)->value = name;
5440 nextId = &(*nextId)->next;
5443 match(T_GREATER, &ast->greater_token);
5448 // objc-class-instance-variables ::= T_LBRACE
5449 // objc-instance-variable-decl-list-opt
5452 bool Parser::parseObjClassInstanceVariables(ObjCInstanceVariablesDeclarationAST *&node)
5455 if (LA() != T_LBRACE)
5458 ObjCInstanceVariablesDeclarationAST *ast = new (_pool) ObjCInstanceVariablesDeclarationAST;
5459 match(T_LBRACE, &ast->lbrace_token);
5461 for (DeclarationListAST **next = &ast->instance_variable_list; LA(); next = &(*next)->next) {
5462 if (LA() == T_RBRACE)
5465 const unsigned start = cursor();
5467 *next = new (_pool) DeclarationListAST;
5468 parseObjCInstanceVariableDeclaration((*next)->value);
5470 if (start == cursor()) {
5471 // skip stray token.
5472 error(cursor(), "skip stray token `%s'", tok().spell());
5477 match(T_RBRACE, &ast->rbrace_token);
5483 // objc-interface-declaration ::= T_AT_REQUIRED
5484 // objc-interface-declaration ::= T_AT_OPTIONAL
5485 // objc-interface-declaration ::= T_SEMICOLON
5486 // objc-interface-declaration ::= objc-property-declaration
5487 // objc-interface-declaration ::= objc-method-prototype
5488 bool Parser::parseObjCInterfaceMemberDeclaration(DeclarationAST *&node)
5504 case T_AT_PROPERTY: {
5505 return parseObjCPropertyDeclaration(node);
5510 ObjCMethodDeclarationAST *ast = new (_pool) ObjCMethodDeclarationAST;
5511 if (parseObjCMethodPrototype(ast->method_prototype)) {
5512 match(T_SEMICOLON, &ast->semicolon_token);
5524 return parseSimpleDeclaration(node);
5528 return parseSimpleDeclaration(node);
5534 // objc-instance-variable-declaration ::= objc-visibility-specifier
5535 // objc-instance-variable-declaration ::= block-declaration
5537 bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
5542 case T_AT_PROTECTED:
5544 case T_AT_PACKAGE: {
5545 ObjCVisibilityDeclarationAST *ast = new (_pool) ObjCVisibilityDeclarationAST;
5546 ast->visibility_token = consumeToken();
5552 return parseSimpleDeclaration(node);
5556 // objc-property-declaration ::=
5557 // T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration
5559 bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&node, SpecifierListAST *attributes)
5562 if (LA() != T_AT_PROPERTY)
5565 ObjCPropertyDeclarationAST *ast = new (_pool) ObjCPropertyDeclarationAST;
5566 ast->attribute_list = attributes;
5567 ast->property_token = consumeToken();
5569 if (LA() == T_LPAREN) {
5570 match(T_LPAREN, &ast->lparen_token);
5572 ObjCPropertyAttributeAST *property_attribute = 0;
5573 if (parseObjCPropertyAttribute(property_attribute)) {
5574 ast->property_attribute_list = new (_pool) ObjCPropertyAttributeListAST;
5575 ast->property_attribute_list->value = property_attribute;
5576 ObjCPropertyAttributeListAST *last = ast->property_attribute_list;
5578 while (LA() == T_COMMA) {
5579 consumeToken(); // consume T_COMMA
5580 last->next = new (_pool) ObjCPropertyAttributeListAST;
5582 if (!parseObjCPropertyAttribute(last->value)) {
5583 error(_tokenIndex, "expected token `%s' got `%s'",
5584 Token::name(T_IDENTIFIER), tok().spell());
5590 match(T_RPAREN, &ast->rparen_token);
5593 if (parseSimpleDeclaration(ast->simple_declaration))
5596 error(_tokenIndex, "expected a simple declaration");
5601 // objc-method-prototype ::= (T_PLUS | T_MINUS) objc-method-decl objc-method-attrs-opt
5603 // objc-method-decl ::= objc-type-name? objc-selector
5604 // objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt
5606 bool Parser::parseObjCMethodPrototype(ObjCMethodPrototypeAST *&node)
5609 if (LA() != T_PLUS && LA() != T_MINUS)
5612 ObjCMethodPrototypeAST *ast = new (_pool) ObjCMethodPrototypeAST;
5613 ast->method_type_token = consumeToken();
5615 parseObjCTypeName(ast->type_name);
5617 if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) {
5618 ObjCSelectorArgumentAST *argument = 0;
5619 ObjCMessageArgumentDeclarationAST *declaration = 0;
5620 parseObjCKeywordDeclaration(argument, declaration);
5622 ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
5623 ast->selector = sel;
5624 ObjCSelectorArgumentListAST *lastSel = new (_pool) ObjCSelectorArgumentListAST;
5625 sel->selector_argument_list = lastSel;
5626 sel->selector_argument_list->value = argument;
5628 ast->argument_list = new (_pool) ObjCMessageArgumentDeclarationListAST;
5629 ast->argument_list->value = declaration;
5630 ObjCMessageArgumentDeclarationListAST *lastArg = ast->argument_list;
5632 while (parseObjCKeywordDeclaration(argument, declaration)) {
5633 lastSel->next = new (_pool) ObjCSelectorArgumentListAST;
5634 lastSel = lastSel->next;
5635 lastSel->value = argument;
5637 lastArg->next = new (_pool) ObjCMessageArgumentDeclarationListAST;
5638 lastArg = lastArg->next;
5639 lastArg->value = declaration;
5642 while (LA() == T_COMMA) {
5645 if (LA() == T_DOT_DOT_DOT) {
5646 ast->dot_dot_dot_token = consumeToken();
5650 // TODO: Is this still valid, and if so, should it be stored in the AST? (EV)
5651 ParameterDeclarationAST *parameter_declaration = 0;
5652 parseParameterDeclaration(parameter_declaration);
5654 } else if (lookAtObjCSelector()) {
5655 ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
5656 sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
5657 sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
5658 parseObjCSelector(sel->selector_argument_list->value->name_token);
5659 ast->selector = sel;
5661 error(cursor(), "expected a selector");
5664 SpecifierListAST **attr = &ast->attribute_list;
5665 while (parseAttributeSpecifier(*attr))
5666 attr = &(*attr)->next;
5672 // objc-property-attribute ::= getter '=' identifier
5673 // objc-property-attribute ::= setter '=' identifier ':'
5674 // objc-property-attribute ::= readonly
5675 // objc-property-attribute ::= readwrite
5676 // objc-property-attribute ::= assign
5677 // objc-property-attribute ::= retain
5678 // objc-property-attribute ::= copy
5679 // objc-property-attribute ::= nonatomic
5680 bool Parser::parseObjCPropertyAttribute(ObjCPropertyAttributeAST *&node)
5683 if (LA() != T_IDENTIFIER)
5686 node = new (_pool) ObjCPropertyAttributeAST;
5688 const Identifier *id = tok().identifier;
5689 const int k = classifyObjectiveCContextKeyword(id->chars(), id->size());
5694 case Token_readonly:
5695 case Token_readwrite:
5696 case Token_nonatomic:
5697 node->attribute_identifier_token = consumeToken();
5700 case Token_getter: {
5701 node->attribute_identifier_token = consumeToken();
5702 match(T_EQUAL, &node->equals_token);
5703 ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
5704 sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
5705 sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
5706 match(T_IDENTIFIER, &sel->selector_argument_list->value->name_token);
5707 node->method_selector = sel;
5711 case Token_setter: {
5712 node->attribute_identifier_token = consumeToken();
5713 match(T_EQUAL, &node->equals_token);
5714 ObjCSelectorAST *sel = new (_pool) ObjCSelectorAST;
5715 sel->selector_argument_list = new (_pool) ObjCSelectorArgumentListAST;
5716 sel->selector_argument_list->value = new (_pool) ObjCSelectorArgumentAST;
5717 match(T_IDENTIFIER, &sel->selector_argument_list->value->name_token);
5718 match(T_COLON, &sel->selector_argument_list->value->colon_token);
5719 node->method_selector = sel;
5728 // objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
5730 bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
5733 if (LA() != T_LPAREN)
5736 ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST;
5737 match(T_LPAREN, &ast->lparen_token);
5738 parseObjCTypeQualifiers(ast->type_qualifier_token);
5739 parseTypeId(ast->type_id);
5740 match(T_RPAREN, &ast->rparen_token);
5745 // objc-selector ::= T_IDENTIFIER | keyword
5747 bool Parser::parseObjCSelector(unsigned &selector_token)
5750 if (! lookAtObjCSelector())
5753 selector_token = consumeToken();
5757 // objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER
5759 bool Parser::parseObjCKeywordDeclaration(ObjCSelectorArgumentAST *&argument, ObjCMessageArgumentDeclarationAST *&node)
5762 if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON)))
5765 node = new (_pool) ObjCMessageArgumentDeclarationAST;
5766 argument = new (_pool) ObjCSelectorArgumentAST;
5768 parseObjCSelector(argument->name_token);
5769 match(T_COLON, &argument->colon_token);
5771 parseObjCTypeName(node->type_name);
5773 SpecifierListAST **attr = &node->attribute_list;
5774 while (parseAttributeSpecifier(*attr))
5775 attr = &(*attr)->next;
5777 SimpleNameAST *param_name = new (_pool) SimpleNameAST;
5778 match(T_IDENTIFIER, ¶m_name->identifier_token);
5779 node->param_name = param_name;
5784 bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
5787 if (LA() != T_IDENTIFIER)
5790 const Identifier *id = tok().identifier;
5791 switch (classifyObjectiveCContextKeyword(id->chars(), id->size())) {
5798 type_qualifier = consumeToken();
5805 bool Parser::peekAtObjCContextKeyword(int kind)
5807 if (LA() != T_IDENTIFIER)
5810 const Identifier *id = tok().identifier;
5811 const int k = classifyObjectiveCContextKeyword(id->chars(), id->size());
5815 bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
5819 if (!peekAtObjCContextKeyword(kind))
5822 in_token = consumeToken();
5826 int Parser::peekAtQtContextKeyword() const
5829 if (LA() != T_IDENTIFIER)
5832 const Identifier *id = tok().identifier;
5833 return classifyQtContextKeyword(id->chars(), id->size());
5836 bool Parser::parseLambdaExpression(ExpressionAST *&node)
5840 LambdaIntroducerAST *lambda_introducer = 0;
5841 if (parseLambdaIntroducer(lambda_introducer)) {
5842 LambdaExpressionAST *ast = new (_pool) LambdaExpressionAST;
5843 ast->lambda_introducer = lambda_introducer;
5844 parseLambdaDeclarator(ast->lambda_declarator);
5845 parseCompoundStatement(ast->statement);
5853 bool Parser::parseLambdaIntroducer(LambdaIntroducerAST *&node)
5856 if (LA() != T_LBRACKET)
5859 LambdaIntroducerAST *ast = new (_pool) LambdaIntroducerAST;
5860 ast->lbracket_token = consumeToken();
5862 if (LA() != T_RBRACKET)
5863 parseLambdaCapture(ast->lambda_capture);
5865 if (LA() == T_RBRACKET) {
5866 ast->rbracket_token = consumeToken();
5868 if (LA() == T_LPAREN || LA() == T_LBRACE) {
5877 bool Parser::parseLambdaCapture(LambdaCaptureAST *&node)
5880 bool startsWithDefaultCapture = false;
5882 unsigned default_capture = 0;
5883 CaptureListAST *capture_list = 0;
5885 if (LA() == T_AMPER || LA() == T_EQUAL) {
5886 if (LA(2) == T_COMMA || LA(2) == T_RBRACKET) {
5887 startsWithDefaultCapture = true;
5888 default_capture = consumeToken(); // consume capture-default
5892 if (startsWithDefaultCapture && LA() == T_COMMA) {
5893 consumeToken(); // consume ','
5894 parseCaptureList(capture_list); // required
5896 } else if (LA() != T_RBRACKET) {
5897 parseCaptureList(capture_list); // optional
5901 LambdaCaptureAST *ast = new (_pool) LambdaCaptureAST;
5902 ast->default_capture_token = default_capture;
5903 ast->capture_list = capture_list;
5909 bool Parser::parseCapture(CaptureAST *&)
5912 if (LA() == T_IDENTIFIER) {
5916 } else if (LA() == T_AMPER && LA(2) == T_IDENTIFIER) {
5921 } else if (LA() == T_THIS) {
5929 bool Parser::parseCaptureList(CaptureListAST *&)
5933 CaptureAST *capture = 0;
5935 if (parseCapture(capture)) {
5936 while (LA() == T_COMMA) {
5937 consumeToken(); // consume `,'
5939 parseCapture(capture);
5946 bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node)
5949 if (LA() != T_LPAREN)
5952 LambdaDeclaratorAST *ast = new (_pool) LambdaDeclaratorAST;
5954 ast->lparen_token = consumeToken(); // consume `('
5955 parseParameterDeclarationClause(ast->parameter_declaration_clause);
5956 match(T_RPAREN, &ast->rparen_token);
5958 SpecifierListAST **attr = &ast->attributes;
5959 while (parseAttributeSpecifier(*attr))
5960 attr = &(*attr)->next;
5962 if (LA() == T_MUTABLE)
5963 ast->mutable_token = consumeToken();
5965 parseExceptionSpecification(ast->exception_specification);
5966 parseTrailingReturnType(ast->trailing_return_type);
5972 bool Parser::parseTrailingReturnType(TrailingReturnTypeAST *&node)
5975 if (LA() != T_ARROW)
5978 TrailingReturnTypeAST *ast = new (_pool) TrailingReturnTypeAST;
5980 ast->arrow_token = consumeToken();
5982 SpecifierListAST **attr = &ast->attributes;
5983 while (parseAttributeSpecifier(*attr))
5984 attr = &(*attr)->next;
5986 parseTrailingTypeSpecifierSeq(ast->type_specifier_list);
5987 parseAbstractDeclarator(ast->declarator, ast->type_specifier_list);
5992 bool Parser::parseTrailingTypeSpecifierSeq(SpecifierListAST *&node)
5995 return parseSimpleTypeSpecifier(node);
5998 void Parser::rewind(unsigned cursor)
6000 #ifndef CPLUSPLUS_NO_DEBUG_RULE
6001 if (cursor != _tokenIndex)
6002 fprintf(stderr, "! rewinding from token %d to token %d\n", _tokenIndex, cursor);
6005 if (cursor < _translationUnit->tokenCount())
6006 _tokenIndex = cursor;
6008 _tokenIndex = _translationUnit->tokenCount() - 1;
6011 void Parser::warning(unsigned index, const char *format, ...)
6014 va_start(args, format);
6016 _translationUnit->message(DiagnosticClient::Warning, index, format, ap);
6021 void Parser::error(unsigned index, const char *format, ...)
6024 va_start(args, format);
6026 _translationUnit->message(DiagnosticClient::Error, index, format, ap);
6031 void Parser::fatal(unsigned index, const char *format, ...)
6034 va_start(args, format);
6036 _translationUnit->message(DiagnosticClient::Fatal, index, format, ap);