[cfe-commits] r124477 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h include/clang/Sema/DeclSpec.h lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDeclCXX.cpp test/CXX/class/class.mem/p8-0x-pedantic.cpp test/CXX/class/class.mem/p8-0x.cpp

Nico Weber nicolasweber at gmx.de
Thu Jan 27 22:07:34 PST 2011


Author: nico
Date: Fri Jan 28 00:07:34 2011
New Revision: 124477

URL: http://llvm.org/viewvc/llvm-project?rev=124477&view=rev
Log:
PR9037: Allow override, final, and new as an extension on inline members.

Added:
    cfe/trunk/test/CXX/class/class.mem/p8-0x-pedantic.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/CXX/class/class.mem/p8-0x.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Jan 28 00:07:34 2011
@@ -394,6 +394,8 @@
 // C++0x override control
 def ext_override_control_keyword : Extension<
   "'%0' keyword accepted as a C++0x extension">, InGroup<CXX0x>;
+def ext_override_inline: Extension<
+  "'%0' keyword only allowed in declarations, allowed as an extension">;
 
 def err_duplicate_virt_specifier : Error<
   "class member already marked '%0'">;

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Jan 28 00:07:34 2011
@@ -910,7 +910,8 @@
   void PopParsingClass();
 
   Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
-                                     const ParsedTemplateInfo &TemplateInfo);
+                                const ParsedTemplateInfo &TemplateInfo,
+                                const VirtSpecifiers& VS);
   void ParseLexedMethodDeclarations(ParsingClass &Class);
   void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
   void ParseLexedMethodDefs(ParsingClass &Class);

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Jan 28 00:07:34 2011
@@ -1513,6 +1513,8 @@
   bool isNewSpecified() const { return Specifiers & VS_New; }
   SourceLocation getNewLoc() const { return VS_newLoc; }
 
+  void clear() { Specifiers = 0; }
+
   static const char *getSpecifierName(Specifier VS);
 
 private:

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Fri Jan 28 00:07:34 2011
@@ -21,7 +21,8 @@
 /// Declarator is a well formed C++ inline method definition. Now lex its body
 /// and store its tokens for parsing after the C++ class is complete.
 Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
-                                const ParsedTemplateInfo &TemplateInfo) {
+                                const ParsedTemplateInfo &TemplateInfo,
+                                const VirtSpecifiers& VS) {
   assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
   assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) &&
          "Current token not a '{', ':' or 'try'!");
@@ -35,11 +36,18 @@
     // FIXME: Friend templates
     FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true,
                                           move(TemplateParams));
-  else // FIXME: pass template information through
+  else { // FIXME: pass template information through
+    if (VS.isOverrideSpecified())
+      Diag(VS.getOverrideLoc(), diag::ext_override_inline) << "override";
+    if (VS.isFinalSpecified())
+      Diag(VS.getFinalLoc(), diag::ext_override_inline) << "final";
+    if (VS.isNewSpecified())
+      Diag(VS.getNewLoc(), diag::ext_override_inline) << "new";
+
     FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
                                            move(TemplateParams), 0, 
-                                           VirtSpecifiers(), 0,
-                                           /*IsDefinition*/true);
+                                           VS, 0, /*IsDefinition*/true);
+  }
 
   HandleMemberFunctionDefaultArgs(D, FnD);
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Jan 28 00:07:34 2011
@@ -1531,6 +1531,7 @@
   }
 
   ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
+  VirtSpecifiers VS;
 
   if (Tok.isNot(tok::colon)) {
     // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
@@ -1547,6 +1548,8 @@
       return;
     }
 
+    ParseOptionalCXX0XVirtSpecifierSeq(VS);
+
     // If attributes exist after the declarator, but before an '{', parse them.
     MaybeParseGNUAttributes(DeclaratorInfo);
 
@@ -1579,7 +1582,7 @@
         return;
       }
 
-      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
+      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS);
       // Consume the optional ';'
       if (Tok.is(tok::semi))
         ConsumeToken();
@@ -1609,7 +1612,6 @@
         SkipUntil(tok::comma, true, true);
     }
 
-    VirtSpecifiers VS;
     ParseOptionalCXX0XVirtSpecifierSeq(VS);
 
     // pure-specifier:
@@ -1689,6 +1691,7 @@
 
     // Parse the next declarator.
     DeclaratorInfo.clear();
+    VS.clear();
     BitfieldSize = 0;
     Init = 0;
     Deleted = false;

Added: cfe/trunk/test/CXX/class/class.mem/p8-0x-pedantic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p8-0x-pedantic.cpp?rev=124477&view=auto
==============================================================================
--- cfe/trunk/test/CXX/class/class.mem/p8-0x-pedantic.cpp (added)
+++ cfe/trunk/test/CXX/class/class.mem/p8-0x-pedantic.cpp Fri Jan 28 00:07:34 2011
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -pedantic -verify %s 
+
+namespace inline_extension {
+  struct Base1 { 
+    virtual void f() {}
+  };
+
+  struct B : Base1 {
+    virtual void f() override {} // expected-warning {{'override' keyword only allowed in declarations, allowed as an extension}}
+    virtual void g() final {} // expected-warning {{'final' keyword only allowed in declarations, allowed as an extension}}
+    virtual void h() new {} // expected-warning {{'new' keyword only allowed in declarations, allowed as an extension}}
+  };
+}
+

Modified: cfe/trunk/test/CXX/class/class.mem/p8-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p8-0x.cpp?rev=124477&r1=124476&r2=124477&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.mem/p8-0x.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mem/p8-0x.cpp Fri Jan 28 00:07:34 2011
@@ -11,10 +11,12 @@
 };
 
 struct Base2 { 
+  virtual void e1(), e2();
   virtual void f();
 };
 
 struct B : Base2 {
+  virtual void e1() override, e2(int);  // No error.
   virtual void f() override;
   void g() override; // expected-error {{only virtual member functions can be marked 'override'}}
   int h override; // expected-error {{only virtual member functions can be marked 'override'}}
@@ -25,3 +27,29 @@
   void g() final; // expected-error {{only virtual member functions can be marked 'final'}}
   int h final; // expected-error {{only virtual member functions can be marked 'final'}}
 };
+
+namespace inline_extension {
+  struct Base1 { 
+    virtual void g() {}
+  };
+
+  struct A : Base1 {
+    virtual void f() new new {} // expected-error {{class member already marked 'new'}}
+    virtual void g() override override {} // expected-error {{class member already marked 'override'}}
+    virtual void h() final final {} // expected-error {{class member already marked 'final'}}
+  };
+
+  struct Base2 { 
+    virtual void f();
+  };
+
+  struct B : Base2 {
+    virtual void f() override {}
+    void g() override {} // expected-error {{only virtual member functions can be marked 'override'}}
+  };
+
+  struct C {
+    virtual void f() final {}
+    void g() final {} // expected-error {{only virtual member functions can be marked 'final'}}
+  };
+}





More information about the cfe-commits mailing list