[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