[cfe-commits] r61650 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/Parser.cpp
Chris Lattner
sabre at nondot.org
Sun Jan 4 15:23:14 PST 2009
Author: lattner
Date: Sun Jan 4 17:23:14 2009
New Revision: 61650
URL: http://llvm.org/viewvc/llvm-project?rev=61650&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=61650&r1=61649&r2=61650&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Jan 4 17:23:14 2009
@@ -267,7 +267,9 @@
/// (if they are typenames). For example, in C we do not expect identifiers
/// inside expressions to be treated as typenames so it will not be called
/// for expressions in C.
- void TryAnnotateTypeOrScopeToken();
+ ///
+ /// This returns true if the token was annotated.
+ bool TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier = 0);
/// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but only
/// annotates C++ scope specifiers.
@@ -607,7 +609,11 @@
/// MaybeParseCXXScopeSpecifier - Parse global scope or nested-name-specifier.
/// Returns true if a nested-name-specifier was parsed from the token stream.
- bool MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS);
+ ///
+ /// If GlobalQualifier is non-null, then it is a :: token we should use as the
+ /// global qualifier.
+ bool MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS,
+ const Token *GlobalQualifier = 0);
//===--------------------------------------------------------------------===//
// C++ 5.2p1: C++ Casts
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=61650&r1=61649&r2=61650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun Jan 4 17:23:14 2009
@@ -478,12 +478,14 @@
// 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 @@
// ::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
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=61650&r1=61649&r2=61650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Jan 4 17:23:14 2009
@@ -29,37 +29,49 @@
/// 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 (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);
+ // '::'
+ if (Tok.is(tok::coloncolon)) {
+ // Global scope.
+ SourceLocation CCLoc = ConsumeToken();
+ SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
+ SS.setEndLoc(CCLoc);
+ }
}
// nested-name-specifier:
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=61650&r1=61649&r2=61650&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Jan 4 17:23:14 2009
@@ -741,14 +741,16 @@
/// 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 @@
// In case the tokens were cached, have Preprocessor replace
// them with the annotation token.
PP.AnnotateCachedTokens(Tok);
- return;
+ return true;
}
}
@@ -785,7 +787,7 @@
// 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 @@
// In case the tokens were cached, have Preprocessor replace them with the
// annotation token.
PP.AnnotateCachedTokens(Tok);
+ return true;
}
/// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
More information about the cfe-commits
mailing list