diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 6c3d5e5d0c2b..03bdc334f755 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -245,10 +245,6 @@ def DLLImport : InheritableAttr { let Spellings = ["dllimport"]; } -def Explicit : InheritableAttr { - let Spellings = []; -} - def FastCall : InheritableAttr { let Spellings = ["fastcall", "__fastcall"]; } diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dd82a46ba277..670b87883e89 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -967,9 +967,6 @@ def err_final_function_overridden : Error< def err_final_base : Error< "derivation from 'final' %0">; -def err_function_overriding_without_override : Error< - "%0 overrides function%s1 without being marked 'override'">; - // C++0x scoped enumerations def err_enum_invalid_underlying : Error< "non-integral type %0 is an invalid underlying type">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d661a040df63..9af8f2cb71dd 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -999,7 +999,7 @@ public: /// C++ record definition's base-specifiers clause and are starting its /// member declarations. void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, - ClassVirtSpecifiers &CVS, + SourceLocation FinalLoc, SourceLocation LBraceLoc); /// ActOnTagFinishDefinition - Invoked once we have finished parsing diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index c50ff4c9dbf9..988ac8422357 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1777,8 +1777,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, SourceLocation LBraceLoc = ConsumeBrace(); + SourceLocation FinalLoc = + CVS.isFinalSpecified() ? CVS.getFinalLoc() : SourceLocation(); + if (TagDecl) - Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, CVS, + Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, LBraceLoc); // C++ 11p3: Members of a class defined with the keyword class are private diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6f98461f44d9..5a4df400f3b3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6714,7 +6714,7 @@ void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { } void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, - ClassVirtSpecifiers &CVS, + SourceLocation FinalLoc, SourceLocation LBraceLoc) { AdjustDeclIfTemplate(TagD); CXXRecordDecl *Record = cast(TagD); @@ -6724,10 +6724,8 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, if (!Record->getIdentifier()) return; - if (CVS.isFinalSpecified()) - Record->addAttr(new (Context) FinalAttr(CVS.getFinalLoc(), Context)); - if (CVS.isExplicitSpecified()) - Record->addAttr(new (Context) ExplicitAttr(CVS.getExplicitLoc(), Context)); + if (FinalLoc.isValid()) + Record->addAttr(new (Context) FinalAttr(FinalLoc, Context)); // C++ [class]p2: // [...] The class-name is also inserted into the scope of the diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index db77d10421e9..3515ad4ed3c0 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -919,26 +919,6 @@ void Sema::CheckOverrideControl(const Decl *D) { << MD->getDeclName(); return; } - - // C++0x [class.derived]p8: - // In a class definition marked with the class-virt-specifier explicit, - // if a virtual member function that is neither implicitly-declared nor a - // destructor overrides a member function of a base class and it is not - // marked with the virt-specifier override, the program is ill-formed. - if (MD->getParent()->hasAttr() && !isa(MD) && - HasOverriddenMethods && !MD->hasAttr()) { - llvm::SmallVector - OverriddenMethods(MD->begin_overridden_methods(), - MD->end_overridden_methods()); - - Diag(MD->getLocation(), diag::err_function_overriding_without_override) - << MD->getDeclName() - << (unsigned)OverriddenMethods.size(); - - for (unsigned I = 0; I != OverriddenMethods.size(); ++I) - Diag(OverriddenMethods[I]->getLocation(), - diag::note_overridden_virtual_function); - } } /// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member diff --git a/clang/test/CXX/class.derived/p8-0x.cpp b/clang/test/CXX/class.derived/p8-0x.cpp deleted file mode 100644 index 6a667f73ec3f..000000000000 --- a/clang/test/CXX/class.derived/p8-0x.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++0x - -namespace Test1 { - -struct A { - virtual void f(); // expected-note {{overridden virtual function is here}} -}; - -struct B explicit : A { - virtual void f(); // expected-error {{overrides function without being marked 'override'}} -}; - -struct C { - virtual ~C(); -}; - -struct D explicit : C { - virtual ~D(); -}; - -} -