From: Chris Lattner Date: Mon, 5 Jan 2009 00:07:25 +0000 (+0000) Subject: sink a call to TryAnnotateCXXScopeToken down into the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e02c47a7085831586344a9728763cb50540c7f7;p=clang sink a call to TryAnnotateCXXScopeToken down into the applicable cases in ParseDeclarationSpecifiers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61657 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 8d57cd60ce..ee748503f6 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -272,8 +272,9 @@ private: bool TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier = 0); /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but only - /// annotates C++ scope specifiers. - void TryAnnotateCXXScopeToken(); + /// annotates C++ scope specifiers. This returns true if the token was + /// annotated. + bool TryAnnotateCXXScopeToken(); /// TentativeParsingAction - An object that is used as a kind of "tentative /// parsing transaction". It gets instantiated to mark the token position and diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index aaf8621294..c063654781 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -438,32 +438,31 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { /// [C++] 'explicit' /// void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, - TemplateParameterLists *TemplateParams) -{ + TemplateParameterLists *TemplateParams){ DS.SetRangeStart(Tok.getLocation()); while (1) { int isInvalid = false; const char *PrevSpec = 0; SourceLocation Loc = Tok.getLocation(); - // Only annotate C++ scope. Allow class-name as an identifier in case - // it's a constructor. - if (getLang().CPlusPlus) - TryAnnotateCXXScopeToken(); - switch (Tok.getKind()) { default: // Try to parse a type-specifier; if we found one, continue. If it's not // a type, this falls through. - if (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec, TemplateParams)) { + if (MaybeParseTypeSpecifier(DS, isInvalid, PrevSpec, TemplateParams)) continue; - } DoneWithDeclSpec: // If this is not a declaration specifier token, we're done reading decl // specifiers. First verify that DeclSpec's are consistent. DS.Finish(Diags, PP.getSourceManager(), getLang()); return; + + case tok::coloncolon: // ::foo::bar + // Annotate C++ scope specifiers. If we get one, loop. + if (TryAnnotateCXXScopeToken()) + continue; + goto DoneWithDeclSpec; case tok::annot_cxxscope: { if (DS.hasTypeSpecifier()) @@ -505,6 +504,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // typedef-name case tok::identifier: { + // In C++, check to see if this is a scope specifier like foo::bar::, if + // so handle it as such. This is important for ctor parsing. + if (getLang().CPlusPlus && + TryAnnotateCXXScopeToken()) + continue; + // This identifier can only be a typedef name if we haven't already seen // a type-specifier. Without this check we misparse: // typedef int X; struct Y { short X; }; as 'short int'. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 29843b1668..bd334e37bd 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -807,17 +807,18 @@ bool Parser::TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier) { } /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only -/// annotates C++ scope specifiers. -void Parser::TryAnnotateCXXScopeToken() { +/// annotates C++ scope specifiers. This returns true if the token was +/// annotated. +bool Parser::TryAnnotateCXXScopeToken() { assert(getLang().CPlusPlus && "Call sites of this function should be guarded by checking for C++"); if (Tok.is(tok::annot_cxxscope)) - return; + return false; CXXScopeSpec SS; if (!MaybeParseCXXScopeSpecifier(SS)) - return; + return false; // Push the current token back into the token stream (or revert it if it is // cached) and use an annotation scope token for current token. @@ -832,4 +833,5 @@ void Parser::TryAnnotateCXXScopeToken() { // In case the tokens were cached, have Preprocessor replace them with the // annotation token. PP.AnnotateCachedTokens(Tok); + return true; }