diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-01-04 23:23:14 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-01-04 23:23:14 +0000 |
| commit | 9a8968b50d8eb0d1c74fed0ba90f5e8fc174d3de (patch) | |
| tree | 3b86ccc8bf169b1b08d8dc9eeb71aedb09f6defc /clang/lib | |
| parent | 7c53a18a08d9ade0e3d8b011f71b955957ab5672 (diff) | |
| download | bcm5719-llvm-9a8968b50d8eb0d1c74fed0ba90f5e8fc174d3de.tar.gz bcm5719-llvm-9a8968b50d8eb0d1c74fed0ba90f5e8fc174d3de.zip | |
my previous patch caused sema to drop the global qualifier, make
sure to pass it down. This makes the code a bit gross, I will clean
it up in subsequent commits.
llvm-svn: 61650
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 35 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 13 |
3 files changed, 49 insertions, 33 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index c1f69465296..c5ed745d829 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -478,12 +478,14 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { // constant: enumeration-constant // Turn a potentially qualified name into a annot_qualtypename or // annot_cxxscope if it would be valid. This handles things like x::y, etc. - TryAnnotateTypeOrScopeToken(); + if (getLang().CPlusPlus) { + TryAnnotateTypeOrScopeToken(); - // If TryAnnotateTypeOrScopeToken modified the current token, then tail - // recurse. - if (Tok.getKind() != tok::identifier) - return ParseCastExpression(isUnaryExpression); + // If TryAnnotateTypeOrScopeToken modified the current token, then tail + // recurse. + if (Tok.getKind() != tok::identifier) + return ParseCastExpression(isUnaryExpression); + } // Consume the identifier so that we can see if it is followed by a '('. // Function designators are allowed to be undeclared (C99 6.5.1p2), so we @@ -630,23 +632,22 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { // ::new -> [C++] new-expression // ::delete -> [C++] delete-expression // ::foo::bar -> global qualified name etc. - SourceLocation ScopeLoc = ConsumeToken(); + Token ColonColonTok = Tok; + ConsumeToken(); if (Tok.is(tok::kw_new)) - return ParseCXXNewExpression(true, ScopeLoc); + return ParseCXXNewExpression(true, ColonColonTok.getLocation()); if (Tok.is(tok::kw_delete)) - return ParseCXXDeleteExpression(true, ScopeLoc); + return ParseCXXDeleteExpression(true, ColonColonTok.getLocation()); // Turn the qualified name into a annot_qualtypename or annot_cxxscope if // it would be valid. - TryAnnotateTypeOrScopeToken(); - - // If we still have a :: as our current token, then this is not a type - // name or scope specifier. - if (Tok.getKind() == tok::coloncolon) { - Diag(Tok, diag::err_expected_expression); - return ExprError(); + if (TryAnnotateTypeOrScopeToken(&ColonColonTok)) { + // If so, retry (tail recurse). + return ParseCastExpression(isUnaryExpression); } - // Otherwise, retry (tail recurse). - return ParseCastExpression(isUnaryExpression); + + // This is not a type name or scope specifier, it is an invalid expression. + Diag(ColonColonTok, diag::err_expected_expression); + return ExprError(); } case tok::kw_new: // [C++] new-expression diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 75e4e1fe7c5..195b52e9885 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -29,37 +29,49 @@ using namespace clang; /// nested-name-specifier identifier '::' /// nested-name-specifier 'template'[opt] simple-template-id '::' [TODO] /// -bool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS) { +bool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS, + const Token *GlobalQualifier) { assert(getLang().CPlusPlus && "Call sites of this function should be guarded by checking for C++."); if (Tok.is(tok::annot_cxxscope)) { + assert(GlobalQualifier == 0 && + "Cannot have :: followed by a resolve annotation scope"); SS.setScopeRep(Tok.getAnnotationValue()); SS.setRange(Tok.getAnnotationRange()); ConsumeToken(); return true; } - if (Tok.isNot(tok::coloncolon) && + if (GlobalQualifier == 0 && + Tok.isNot(tok::coloncolon) && (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon))) return false; // ::new and ::delete aren't nested-name-specifiers, so parsing the :: as // a scope specifier only makes things more complicated. - if (Tok.is(tok::coloncolon)) { + if (GlobalQualifier == 0 && Tok.is(tok::coloncolon)) { Token Next = NextToken(); if (Next.is(tok::kw_new) || Next.is(tok::kw_delete)) return false; } - SS.setBeginLoc(Tok.getLocation()); - - // '::' - if (Tok.is(tok::coloncolon)) { - // Global scope. - SourceLocation CCLoc = ConsumeToken(); - SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); - SS.setEndLoc(CCLoc); + if (GlobalQualifier) { + // Pre-parsed '::'. + SS.setBeginLoc(GlobalQualifier->getLocation()); + SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, + GlobalQualifier->getLocation())); + SS.setEndLoc(GlobalQualifier->getLocation()); + } else { + SS.setBeginLoc(Tok.getLocation()); + + // '::' + if (Tok.is(tok::coloncolon)) { + // Global scope. + SourceLocation CCLoc = ConsumeToken(); + SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); + SS.setEndLoc(CCLoc); + } } // nested-name-specifier: diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 381c84e3178..29843b16689 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -741,14 +741,16 @@ Parser::OwningExprResult Parser::ParseSimpleAsm() { /// will not be called twice, once to check whether we have a declaration /// specifier, and another one to get the actual type inside /// ParseDeclarationSpecifiers). -void Parser::TryAnnotateTypeOrScopeToken() { +/// +/// This returns true if the token was annotated. +bool Parser::TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier) { // FIXME: what about template-ids? if (Tok.is(tok::annot_qualtypename) || Tok.is(tok::annot_cxxscope)) - return; + return false; CXXScopeSpec SS; if (getLang().CPlusPlus) - MaybeParseCXXScopeSpecifier(SS); + MaybeParseCXXScopeSpecifier(SS, GlobalQualifier); if (Tok.is(tok::identifier)) { DeclTy *Template = 0; @@ -772,7 +774,7 @@ void Parser::TryAnnotateTypeOrScopeToken() { // In case the tokens were cached, have Preprocessor replace // them with the annotation token. PP.AnnotateCachedTokens(Tok); - return; + return true; } } @@ -785,7 +787,7 @@ void Parser::TryAnnotateTypeOrScopeToken() { // names a type. if (SS.isEmpty()) - return; + return false; // A C++ scope specifier that isn't followed by a typename. // Push the current token back into the token stream (or revert it if it is @@ -801,6 +803,7 @@ void Parser::TryAnnotateTypeOrScopeToken() { // In case the tokens were cached, have Preprocessor replace them with the // annotation token. PP.AnnotateCachedTokens(Tok); + return true; } /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only |

