[cfe-commits] r61659 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Parse/ParseExprCXX.cpp lib/Parse/Parser.cpp
Chris Lattner
sabre at nondot.org
Sun Jan 4 16:13:00 PST 2009
Author: lattner
Date: Sun Jan 4 18:13:00 2009
New Revision: 61659
URL: http://llvm.org/viewvc/llvm-project?rev=61659&view=rev
Log:
ParseCXXSimpleTypeSpecifier can only be called on things that are
verified to be simple type specifiers, so there is no need for it
to call TryAnnotateTypeOrScopeToken.
Make MaybeParseCXXScopeSpecifier reject ::new and ::delete with a
hard error now that it may never be transitively called in a
context where these are legal. This allows me to start
disentangling things more.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/Parser.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=61659&r1=61658&r2=61659&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sun Jan 4 18:13:00 2009
@@ -1309,6 +1309,8 @@
"array size must be specified in new expressions")
DIAG(err_bad_new_type, ERROR,
"cannot allocate %select{function|incomplete|reference}1 type %0 with new")
+DIAG(err_invalid_qualified_new_delete, ERROR,
+ "invalid use of ::%select{new|delete}0")
DIAG(err_new_array_nonconst, ERROR,
"only the first dimension of an allocated array may be non-const")
DIAG(err_array_size_not_integral, ERROR,
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=61659&r1=61658&r2=61659&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Jan 4 18:13:00 2009
@@ -19,6 +19,9 @@
/// MaybeParseCXXScopeSpecifier - Parse global scope or nested-name-specifier.
/// Returns true if a nested-name-specifier was parsed from the token stream.
+///
+/// Note that this routine emits an error if you call it with ::new or ::delete
+/// as the current tokens, so only call it in contexts where these are invalid.
///
/// '::'[opt] nested-name-specifier
/// '::'
@@ -36,7 +39,7 @@
if (Tok.is(tok::annot_cxxscope)) {
assert(GlobalQualifier == 0 &&
- "Cannot have :: followed by a resolve annotation scope");
+ "Cannot have :: followed by a resolved annotation scope");
SS.setScopeRep(Tok.getAnnotationValue());
SS.setRange(Tok.getAnnotationRange());
ConsumeToken();
@@ -48,27 +51,33 @@
(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 (GlobalQualifier == 0 && Tok.is(tok::coloncolon)) {
- Token Next = NextToken();
- if (Next.is(tok::kw_new) || Next.is(tok::kw_delete))
- return false;
- }
-
if (GlobalQualifier) {
// Pre-parsed '::'.
SS.setBeginLoc(GlobalQualifier->getLocation());
SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope,
GlobalQualifier->getLocation()));
SS.setEndLoc(GlobalQualifier->getLocation());
+
+ assert(Tok.isNot(tok::kw_new) && Tok.isNot(tok::kw_delete) &&
+ "Never called with preparsed :: qualifier and with new/delete");
} else {
SS.setBeginLoc(Tok.getLocation());
- // '::'
+ // '::' - Global scope qualifier.
if (Tok.is(tok::coloncolon)) {
- // Global scope.
SourceLocation CCLoc = ConsumeToken();
+
+ // ::new and ::delete aren't nested-name-specifiers, and
+ // MaybeParseCXXScopeSpecifier is never called in a context where one could
+ // exist. This means that if we see it, we have a syntax error.
+ if (Tok.is(tok::kw_new) || Tok.is(tok::kw_delete)) {
+ Diag(Tok, diag::err_invalid_qualified_new_delete)
+ << Tok.is(tok::kw_delete);
+ SS.setBeginLoc(SourceLocation());
+ return false;
+ }
+
+ // Global scope.
SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
SS.setEndLoc(CCLoc);
}
@@ -450,18 +459,18 @@
/// typedef-name
///
void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
- // Annotate typenames and C++ scope specifiers.
- TryAnnotateTypeOrScopeToken();
-
DS.SetRangeStart(Tok.getLocation());
const char *PrevSpec;
SourceLocation Loc = Tok.getLocation();
switch (Tok.getKind()) {
+ case tok::identifier: // foo::bar
+ case tok::coloncolon: // ::foo::bar
+ assert(0 && "Annotation token should already be formed!");
default:
assert(0 && "Not a simple-type-specifier token!");
abort();
-
+
// type-name
case tok::annot_qualtypename: {
DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=61659&r1=61658&r2=61659&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Jan 4 18:13:00 2009
@@ -743,6 +743,9 @@
/// ParseDeclarationSpecifiers).
///
/// This returns true if the token was annotated.
+///
+/// Note that this routine emits an error if you call it with ::new or ::delete
+/// as the current tokens, so only call it in contexts where these are invalid.
bool Parser::TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier) {
// FIXME: what about template-ids?
if (Tok.is(tok::annot_qualtypename) || Tok.is(tok::annot_cxxscope))
@@ -809,6 +812,9 @@
/// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
/// annotates C++ scope specifiers. This returns true if the token was
/// annotated.
+///
+/// Note that this routine emits an error if you call it with ::new or ::delete
+/// as the current tokens, so only call it in contexts where these are invalid.
bool Parser::TryAnnotateCXXScopeToken() {
assert(getLang().CPlusPlus &&
"Call sites of this function should be guarded by checking for C++");
More information about the cfe-commits
mailing list