[cfe-commits] r95255 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp test/CXX/dcl.decl/dcl.name/p1.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Wed Feb 3 13:21:43 PST 2010


Author: cornedbee
Date: Wed Feb  3 15:21:43 2010
New Revision: 95255

URL: http://llvm.org/viewvc/llvm-project?rev=95255&view=rev
Log:
In some contexts, type declarations cannot occur. Pass this information down to ParseClassSpecifier, to make its decision easier. Fixes PR6200.

Added:
    cfe/trunk/test/CXX/dcl.decl/dcl.name/p1.cpp
Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=95255&r1=95254&r2=95255&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Feb  3 15:21:43 2010
@@ -1065,7 +1065,8 @@
   bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
                                   const char *&PrevSpec,
                                   unsigned &DiagID,
-               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                                  bool SuppressDeclarations = false);
 
   void ParseSpecifierQualifierList(DeclSpec &DS);
 
@@ -1311,7 +1312,8 @@
   void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
                            DeclSpec &DS,
                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-                           AccessSpecifier AS = AS_none);
+                           AccessSpecifier AS = AS_none,
+                           bool SuppressDeclarations = false);
   void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
                                    DeclPtrTy TagDecl);
   void ParseCXXClassMemberDeclaration(AccessSpecifier AS,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=95255&r1=95254&r2=95255&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Feb  3 15:21:43 2010
@@ -1398,7 +1398,8 @@
 bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
                                         const char *&PrevSpec,
                                         unsigned &DiagID,
-                                      const ParsedTemplateInfo &TemplateInfo) {
+                                        const ParsedTemplateInfo &TemplateInfo,
+                                        bool SuppressDeclarations) {
   SourceLocation Loc = Tok.getLocation();
 
   switch (Tok.getKind()) {
@@ -1408,7 +1409,7 @@
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
       return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
-                                        TemplateInfo);
+                                        TemplateInfo, SuppressDeclarations);
     // Otherwise, not a type specifier.
     return false;
   case tok::coloncolon:   // ::foo::bar
@@ -1420,7 +1421,7 @@
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
       return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
-                                        TemplateInfo);
+                                        TemplateInfo, SuppressDeclarations);
     // Otherwise, not a type specifier.
     return false;
 
@@ -1526,7 +1527,8 @@
   case tok::kw_union: {
     tok::TokenKind Kind = Tok.getKind();
     ConsumeToken();
-    ParseClassSpecifier(Kind, Loc, DS, TemplateInfo);
+    ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS_none,
+                        SuppressDeclarations);
     return true;
   }
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=95255&r1=95254&r2=95255&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Feb  3 15:21:43 2010
@@ -547,7 +547,7 @@
 /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
 /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
 /// until we reach the start of a definition or see a token that
-/// cannot start a definition.
+/// cannot start a definition. If SuppressDeclarations is true, we do know.
 ///
 ///       class-specifier: [C++ class]
 ///         class-head '{' member-specification[opt] '}'
@@ -587,7 +587,7 @@
 void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                                  SourceLocation StartLoc, DeclSpec &DS,
                                  const ParsedTemplateInfo &TemplateInfo,
-                                 AccessSpecifier AS) {
+                                 AccessSpecifier AS, bool SuppressDeclarations){
   DeclSpec::TST TagType;
   if (TagTokKind == tok::kw_struct)
     TagType = DeclSpec::TST_struct;
@@ -733,8 +733,16 @@
   // have to be treated differently.  If we have 'struct foo {...' or
   // 'struct foo :...' then this is a definition. Otherwise we have
   // something like 'struct foo xyz', a reference.
+  // However, in some contexts, things look like declarations but are just
+  // references, e.g.
+  // new struct s;
+  // or
+  // &T::operator struct s;
+  // For these, SuppressDeclarations is true.
   Action::TagUseKind TUK;
-  if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) {
+  if (SuppressDeclarations)
+    TUK = Action::TUK_Reference;
+  else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){
     if (DS.isFriendSpecified()) {
       // C++ [class.friend]p2:
       //   A class shall not be defined in a friend declaration.

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=95255&r1=95254&r2=95255&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Feb  3 15:21:43 2010
@@ -763,12 +763,15 @@
   bool isInvalid = 0;
 
   // Parse one or more of the type specifiers.
-  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) {
+  if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+      ParsedTemplateInfo(), /*SuppressDeclarations*/true)) {
     Diag(Tok, diag::err_operator_missing_type_specifier);
     return true;
   }
 
-  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID)) ;
+  while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+         ParsedTemplateInfo(), /*SuppressDeclarations*/true))
+  {}
 
   return false;
 }

Added: cfe/trunk/test/CXX/dcl.decl/dcl.name/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.name/p1.cpp?rev=95255&view=auto

==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.name/p1.cpp (added)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.name/p1.cpp Wed Feb  3 15:21:43 2010
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace pr6200 {
+  struct v {};
+  struct s {
+    int i;
+    operator struct v() { return v(); };
+  };
+
+  void f()
+  {
+    // Neither of these is a declaration.
+    (void)new struct s;
+    (void)&s::operator struct v;
+  }
+}





More information about the cfe-commits mailing list