summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/Parser.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-01-06 16:15:05 +0100
committerRoberto Raggi <roberto.raggi@nokia.com>2010-01-06 16:15:28 +0100
commit83d5659454ffcfa2b6299253dc57b08699f97959 (patch)
treefab58a952f3a534bd24383251f30d3ad989e7d82 /src/shared/cplusplus/Parser.cpp
parentc4ba8a021bbb0078e6b143a21c7d03525d2022aa (diff)
downloadqt-creator-83d5659454ffcfa2b6299253dc57b08699f97959.tar.gz
Fixed parsing of friend class declarations.
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r--src/shared/cplusplus/Parser.cpp54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 44467c8584..d66457ea9e 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -204,7 +204,7 @@ void Parser::skipUntilDeclaration()
lookAtFunctionSpecifier() || lookAtStorageClassSpecifier())
return;
} // switch
- }
+ }
}
bool Parser::skipUntilStatement()
@@ -439,6 +439,7 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
(*decl)->value = declaration;
decl = &(*decl)->next;
} else {
+ _translationUnit->error(start_declaration, "expected a declaration");
rewind(start_declaration + 1);
skipUntilDeclaration();
}
@@ -568,6 +569,7 @@ bool Parser::parseLinkageBody(DeclarationAST *&node)
(*declaration_ptr)->value = declaration;
declaration_ptr = &(*declaration_ptr)->next;
} else {
+ _translationUnit->error(start_declaration, "expected a declaration");
rewind(start_declaration + 1);
skipUntilDeclaration();
}
@@ -1601,6 +1603,7 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
(*declaration_ptr)->value = declaration;
declaration_ptr = &(*declaration_ptr)->next;
} else {
+ _translationUnit->error(start_declaration, "expected a declaration");
rewind(start_declaration + 1);
skipUntilDeclaration();
}
@@ -2857,21 +2860,24 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
DeclaratorListAST *declarator_list = 0,
**declarator_ptr = &declarator_list;
- const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier);
DeclaratorAST *declarator = 0;
- if (! parseInitDeclarator(declarator, acceptStructDeclarator) && maybeCtor) {
- rewind(startOfNamedTypeSpecifier);
- named_type_specifier = 0;
- // pop the named type specifier from the decl-specifier-seq
- SpecifierListAST **spec_ptr = &decl_specifier_seq;
- for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) {
- if (! (*spec_ptr)->next) {
- *spec_ptr = 0;
- break;
+
+ if (LA() != T_SEMICOLON) {
+ const bool maybeCtor = (LA() == T_LPAREN && named_type_specifier);
+ if (! parseInitDeclarator(declarator, acceptStructDeclarator) && maybeCtor) {
+ rewind(startOfNamedTypeSpecifier);
+ named_type_specifier = 0;
+ // pop the named type specifier from the decl-specifier-seq
+ SpecifierListAST **spec_ptr = &decl_specifier_seq;
+ for (; *spec_ptr; spec_ptr = &(*spec_ptr)->next) {
+ if (! (*spec_ptr)->next) {
+ *spec_ptr = 0;
+ break;
+ }
}
+ if (! parseInitDeclarator(declarator, acceptStructDeclarator))
+ return false;
}
- if (! parseInitDeclarator(declarator, acceptStructDeclarator))
- return false;
}
// if there is no valid declarator
@@ -2955,11 +2961,23 @@ bool Parser::parseSimpleDeclaration(DeclarationAST *&node,
bool Parser::maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const
{
// look at the decl_specifier for possible fwd or class declarations.
- if (SpecifierListAST *spec = decl_specifier_seq) {
- if (! spec->next && (spec->value->asElaboratedTypeSpecifier() ||
- spec->value->asEnumSpecifier() ||
- spec->value->asClassSpecifier()))
- return true;
+ if (SpecifierListAST *it = decl_specifier_seq) {
+ while (it) {
+ SimpleSpecifierAST *spec = it->value->asSimpleSpecifier();
+ if (spec && _translationUnit->tokenKind(spec->specifier_token) == T_FRIEND)
+ it = it->next;
+ else
+ break;
+ }
+
+ if (it) {
+ SpecifierAST *spec = it->value;
+
+ if (! it->next && (spec->asElaboratedTypeSpecifier() ||
+ spec->asEnumSpecifier() ||
+ spec->asClassSpecifier()))
+ return true;
+ }
}
return false;