]> granicus.if.org Git - clang/commitdiff
Use attributes for all the override control specifiers.
authorAnders Carlsson <andersca@mac.com>
Mon, 24 Jan 2011 16:26:15 +0000 (16:26 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 24 Jan 2011 16:26:15 +0000 (16:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124122 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/clang/AST/Decl.h
include/clang/AST/DeclCXX.h
include/clang/Basic/Attr.td
lib/AST/DeclCXX.cpp
lib/CodeGen/CGExprCXX.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriter.cpp
lib/Serialization/ASTWriterDecl.cpp

index 25424ce85327d706f291b28a3e14c67d7ff0e5e3..a34a2ef5355cb0111f8c1a47bff7ae9572bfeac0 100644 (file)
@@ -1195,8 +1195,6 @@ private:
   bool IsDeleted : 1;
   bool IsTrivial : 1; // sunk from CXXMethodDecl
   bool HasImplicitReturnZero : 1;
-  bool IsMarkedOverride : 1; // sunk from CXXMethodDecl
-  bool IsMarkedFinal : 1; // sunk from CXXMethodDecl
 
   /// \brief End part of this FunctionDecl's source range.
   ///
@@ -1276,8 +1274,7 @@ protected:
       IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
       IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
       HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
-      HasImplicitReturnZero(false), IsMarkedOverride(false), 
-      IsMarkedFinal(false), EndRangeLoc(NameInfo.getEndLoc()),
+      HasImplicitReturnZero(false), EndRangeLoc(NameInfo.getEndLoc()),
       TemplateOrSpecialization(),
       DNLoc(NameInfo.getInfo()) {}
 
@@ -1390,16 +1387,6 @@ public:
   bool hasImplicitReturnZero() const { return HasImplicitReturnZero; }
   void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; }
 
-  /// \brief Whether this member function is marked with the 'override' keyword,
-  /// C++0x [class.mem]p8.
-  bool isMarkedOverride() const { return IsMarkedOverride; }
-  void setIsMarkedOverride(bool IMO) { IsMarkedOverride = IMO; }
-
-  /// \brief Whether this member function is marked with the 'final' keyword,
-  /// C++0x [class.mem]p8.
-  bool isMarkedFinal() const { return IsMarkedFinal; }
-  void setIsMarkedFinal(bool IMF) { IsMarkedFinal = IMF; }
-
   /// \brief Whether this function has a prototype, either because one
   /// was explicitly written or because it was "inherited" by merging
   /// a declaration without a prototype with a declaration that has a
index cc3e4a52aa64e4f99d37f8c032c5e792c9da2cd0..a09fd6741b88c39fd9971831158adad6f2141518 100644 (file)
@@ -356,12 +356,6 @@ class CXXRecordDecl : public RecordDecl {
     /// \brief Whether we have already declared a destructor within the class.
     bool DeclaredDestructor : 1;
 
-    /// \brief Whether this class is marked 'final'.
-    bool IsMarkedFinal : 1;
-
-    /// \brief Whether this class is marked 'explicit'.
-    bool IsMarkedExplicit : 1;
-
     /// NumBases - The number of base class specifiers in Bases.
     unsigned NumBases;
     
@@ -665,18 +659,6 @@ public:
   /// This value is used for lazy creation of destructors.
   bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
 
-  /// \brief Whether this class is marked 'final'.
-  bool isMarkedFinal() const { return data().IsMarkedFinal; }
-
-  /// \brief Mark this class as 'final'.
-  void setIsMarkedFinal(bool IMF) { data().IsMarkedFinal = IMF; }
-
-  /// \brief Whether this class is marked 'explicit'.
-  bool isMarkedExplicit() const { return data().IsMarkedExplicit; }
-
-  /// \brief Mark this class as 'explicit'.
-  void setIsMarkedExplicit(bool IME) { data().IsMarkedExplicit = IME; }
-
   /// getConversions - Retrieve the overload set containing all of the
   /// conversion functions in this class.
   UnresolvedSetImpl *getConversionFunctions() {
index 9a13ce639102d37eb0b5679872721032644e09b9..49d3ab62392853b110b588fcddc5acd80e3734ca 100644 (file)
@@ -213,10 +213,18 @@ def DLLImport : InheritableAttr {
   let Spellings = ["dllimport"];
 }
 
+def Explicit : InheritableAttr {
+  let Spellings = [];
+}
+
 def FastCall : InheritableAttr {
   let Spellings = ["fastcall", "__fastcall"];
 }
 
+def Final : InheritableAttr { 
+  let Spellings = [];
+}
+
 def Format : InheritableAttr {
   let Spellings = ["format"];
   let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">,
@@ -336,6 +344,10 @@ def Overloadable : Attr {
   let Spellings = ["overloadable"];
 }
 
+def Override : InheritableAttr { 
+  let Spellings = [];
+}
+
 def Ownership : InheritableAttr {
   let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
   let Args = [EnumArgument<"OwnKind", "OwnershipKind",
index 370cbfc0f1b6e4f55db9f54f8375b7cfdfb3f36e..bce8b92c480e092b47011bd3aeff667943f49b24 100644 (file)
@@ -36,9 +36,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
     HasTrivialDestructor(true), ComputedVisibleConversions(false),
     DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), 
     DeclaredCopyAssignment(false), DeclaredDestructor(false),
-    IsMarkedFinal(false), IsMarkedExplicit(false),
-    NumBases(0), NumVBases(0), Bases(), VBases(), 
-    Definition(D), FirstFriend(0) {
+    NumBases(0), NumVBases(0), Bases(), VBases(),
+  Definition(D), FirstFriend(0) {
 }
 
 CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
index 9ce90c0ce8e917e57e3b4c63c4bf7111affbc10a..7177a64e74bcb55ce6744585ed3e903ce81fd812 100644 (file)
@@ -65,12 +65,12 @@ static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context,
 
   // If the member function is marked 'final', we know that it can't be
   // overridden and can therefore devirtualize it.
-  if (MD->isMarkedFinal())
+  if (MD->hasAttr<FinalAttr>())
     return true;
 
   // Similarly, if the class itself is marked 'final' it can't be overridden
   // and we can therefore devirtualize the member function call.
-  if (MD->getParent()->isMarkedFinal())
+  if (MD->getParent()->hasAttr<FinalAttr>())
     return true;
 
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) {
index 85df57a76c7af5b6fcdda2e776e64604437f994d..4d8179738a0eb4a492a49901b47df9dc3aae06b6 100644 (file)
@@ -6386,8 +6386,10 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
   if (!Record->getIdentifier())
     return;
 
-  Record->setIsMarkedFinal(CVS.isFinalSpecified());
-  Record->setIsMarkedExplicit(CVS.isExplicitSpecified());
+  if (CVS.isFinalSpecified())
+    Record->addAttr(new (Context) FinalAttr(CVS.getFinalLoc(), Context));
+  if (CVS.isExplicitSpecified())
+    Record->addAttr(new (Context) ExplicitAttr(CVS.getExplicitLoc(), Context));
     
   // C++ [class]p2:
   //   [...] The class-name is also inserted into the scope of the
index eeb665b61db3644261b97425acbec6f5c6136021..25d0a5effed95c687e8281b1cbd4fb02069f0094 100644 (file)
@@ -525,7 +525,7 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   //   If a class is marked with the class-virt-specifier final and it appears
   //   as a base-type-specifier in a base-clause (10 class.derived), the program
   //   is ill-formed.
-  if (CXXBaseDecl->isMarkedFinal()) {
+  if (CXXBaseDecl->hasAttr<FinalAttr>()) {
     Diag(BaseLoc, diag::err_class_marked_final_used_as_base) 
       << CXXBaseDecl->getDeclName();
     Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
@@ -871,7 +871,7 @@ void Sema::CheckOverrideControl(const Decl *D) {
   //   the program is ill-formed.
   bool HasOverriddenMethods = 
     MD->begin_overridden_methods() != MD->end_overridden_methods();
-  if (MD->isMarkedOverride() && !HasOverriddenMethods) {
+  if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods) {
     Diag(MD->getLocation(), 
                  diag::err_function_marked_override_not_overriding)
       << MD->getDeclName();
@@ -883,8 +883,8 @@ void Sema::CheckOverrideControl(const Decl *D) {
   //   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()->isMarkedExplicit() && !isa<CXXDestructorDecl>(MD) &&
-      HasOverriddenMethods && !MD->isMarkedOverride()) {
+  if (MD->getParent()->hasAttr<ExplicitAttr>() && !isa<CXXDestructorDecl>(MD) &&
+      HasOverriddenMethods && !MD->hasAttr<OverrideAttr>()) {
     llvm::SmallVector<const CXXMethodDecl*, 4> 
       OverriddenMethods(MD->begin_overridden_methods(), 
                         MD->end_overridden_methods());
@@ -904,7 +904,7 @@ void Sema::CheckOverrideControl(const Decl *D) {
 /// C++0x [class.virtual]p3.
 bool Sema::CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New,
                                                   const CXXMethodDecl *Old) {
-  if (!Old->isMarkedFinal())
+  if (!Old->hasAttr<FinalAttr>())
     return false;
 
   Diag(New->getLocation(), diag::err_final_function_overridden)
@@ -1057,7 +1057,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
            diag::override_keyword_only_allowed_on_virtual_member_functions)
         << "override" << FixItHint::CreateRemoval(VS.getOverrideLoc());
     } else
-      MD->setIsMarkedOverride(true);
+      MD->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context));
   }
   if (VS.isFinalSpecified()) {
     CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
@@ -1066,7 +1066,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
            diag::override_keyword_only_allowed_on_virtual_member_functions)
       << "final" << FixItHint::CreateRemoval(VS.getFinalLoc());
     } else
-      MD->setIsMarkedFinal(true);
+      MD->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context));
   }
 
   CheckOverrideControl(Member);
index 2102073682da533b4093b1e88308b31dc1d4cf82..45fde296e3cc13afc4f6659cfadd881f224a955f 100644 (file)
@@ -1640,9 +1640,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
   
   Instantiation->setTagKind(Pattern->getTagKind());
 
-  Instantiation->setIsMarkedFinal(Pattern->isMarkedFinal());
-  Instantiation->setIsMarkedExplicit(Pattern->isMarkedExplicit());
-
   // Do substitution on the base class specifiers.
   if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
     Invalid = true;
index 5238ad6dfc8877dbd7de10098e53aa8028b28d6e..759e2c16f1dbf471b942e5de0f8974795d372046 100644 (file)
@@ -1389,8 +1389,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   if (D->isPure())
     SemaRef.CheckPureMethod(Method, SourceRange());
 
-  Method->setIsMarkedOverride(D->isMarkedOverride());
-  Method->setIsMarkedFinal(D->isMarkedFinal());
   Method->setAccess(D->getAccess());
 
   SemaRef.CheckOverrideControl(Method);
index 453820cc4ab6238ddc11d5ada3c9a8b8263104a2..26baee47c223059f34129021cd236effc68ae9ad 100644 (file)
@@ -395,9 +395,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   FD->IsDeleted = Record[Idx++];
   FD->IsTrivial = Record[Idx++];
   FD->HasImplicitReturnZero = Record[Idx++];
-  FD->IsMarkedOverride = Record[Idx++];
-  FD->IsMarkedFinal = Record[Idx++];
-
   FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
 
   // Read in the parameters.
@@ -800,8 +797,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
   Data.DeclaredCopyConstructor = Record[Idx++];
   Data.DeclaredCopyAssignment = Record[Idx++];
   Data.DeclaredDestructor = Record[Idx++];
-  Data.IsMarkedFinal = Record[Idx++];
-  Data.IsMarkedExplicit = Record[Idx++];
 
   Data.NumBases = Record[Idx++];
   if (Data.NumBases)
index ea6b80762a4696e83436a699e619fc979654e5a6..1e296e85143fdd65b902a596013a62437312d845 100644 (file)
@@ -3394,8 +3394,6 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec
   Record.push_back(Data.DeclaredCopyConstructor);
   Record.push_back(Data.DeclaredCopyAssignment);
   Record.push_back(Data.DeclaredDestructor);
-  Record.push_back(Data.IsMarkedFinal);
-  Record.push_back(Data.IsMarkedExplicit);
 
   Record.push_back(Data.NumBases);
   if (Data.NumBases > 0)
index 88ff1a7c9bb5b6fd892b7c66f4535e612299fbe9..507c66931c555345dd0f94b034ef0ef0e9bd6884 100644 (file)
@@ -312,8 +312,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   Record.push_back(D->isDeleted());
   Record.push_back(D->isTrivial());
   Record.push_back(D->hasImplicitReturnZero());
-  Record.push_back(D->isMarkedOverride());
-  Record.push_back(D->isMarkedFinal());
   Writer.AddSourceLocation(D->getLocEnd(), Record);
 
   Record.push_back(D->param_size());