aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp68
1 files changed, 59 insertions, 9 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index a410dfeda3..aaf8621294 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -700,12 +700,28 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
bool Parser::MaybeParseTypeSpecifier(DeclSpec &DS, int& isInvalid,
const char *&PrevSpec,
TemplateParameterLists *TemplateParams) {
- // Annotate typenames and C++ scope specifiers.
- TryAnnotateTypeOrScopeToken();
-
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
+ case tok::identifier: // foo::bar
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec, TemplateParams);
+ // Otherwise, not a type specifier.
+ return false;
+ case tok::coloncolon: // ::foo::bar
+ if (NextToken().is(tok::kw_new) || // ::new
+ NextToken().is(tok::kw_delete)) // ::delete
+ return false;
+
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec, TemplateParams);
+ // Otherwise, not a type specifier.
+ return false;
+
// simple-type-specifier:
case tok::annot_qualtypename: {
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
@@ -1171,11 +1187,28 @@ bool Parser::isTypeQualifier() const {
/// isTypeSpecifierQualifier - Return true if the current token could be the
/// start of a specifier-qualifier-list.
bool Parser::isTypeSpecifierQualifier() {
- // Annotate typenames and C++ scope specifiers.
- TryAnnotateTypeOrScopeToken();
-
switch (Tok.getKind()) {
default: return false;
+
+ case tok::identifier: // foo::bar
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return isTypeSpecifierQualifier();
+ // Otherwise, not a type specifier.
+ return false;
+ case tok::coloncolon: // ::foo::bar
+ if (NextToken().is(tok::kw_new) || // ::new
+ NextToken().is(tok::kw_delete)) // ::delete
+ return false;
+
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return isTypeSpecifierQualifier();
+ // Otherwise, not a type specifier.
+ return false;
+
// GNU attributes support.
case tok::kw___attribute:
// GNU typeof support.
@@ -1230,11 +1263,28 @@ bool Parser::isTypeSpecifierQualifier() {
/// isDeclarationSpecifier() - Return true if the current token is part of a
/// declaration specifier.
bool Parser::isDeclarationSpecifier() {
- // Annotate typenames and C++ scope specifiers.
- TryAnnotateTypeOrScopeToken();
-
switch (Tok.getKind()) {
default: return false;
+
+ case tok::identifier: // foo::bar
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return isDeclarationSpecifier();
+ // Otherwise, not a declaration specifier.
+ return false;
+ case tok::coloncolon: // ::foo::bar
+ if (NextToken().is(tok::kw_new) || // ::new
+ NextToken().is(tok::kw_delete)) // ::delete
+ return false;
+
+ // Annotate typenames and C++ scope specifiers. If we get one, just
+ // recurse to handle whatever we get.
+ if (TryAnnotateTypeOrScopeToken())
+ return isDeclarationSpecifier();
+ // Otherwise, not a declaration specifier.
+ return false;
+
// storage-class-specifier
case tok::kw_typedef:
case tok::kw_extern: