aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExprCXX.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-04 23:23:14 +0000
committerChris Lattner <sabre@nondot.org>2009-01-04 23:23:14 +0000
commita7bc7c880f86bc180684ef032d06df51bcae7a23 (patch)
tree4f12a3f17beda17b06035f9aa4b90c31816b2443 /lib/Parse/ParseExprCXX.cpp
parent74ba410e4df194f99021e4d2dda494c853444482 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61650 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r--lib/Parse/ParseExprCXX.cpp34
1 files changed, 23 insertions, 11 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 75e4e1fe7c..195b52e988 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/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: