[cfe-commits] r102020 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaAccess.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaInit.h test/CXX/class.access/p4.cpp

Anders Carlsson andersca at mac.com
Wed Apr 21 12:52:01 PDT 2010


Author: andersca
Date: Wed Apr 21 14:52:01 2010
New Revision: 102020

URL: http://llvm.org/viewvc/llvm-project?rev=102020&view=rev
Log:
Keep tack of whether a base in an InitializedEntity is an inherited virtual base or not. Use this in CheckConstructorAccess.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaAccess.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaInit.h
    cfe/trunk/test/CXX/class.access/p4.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 21 14:52:01 2010
@@ -462,6 +462,10 @@
 def err_access_ctor_base :
     Error<"base class %0 has %select{private|protected}1 constructor">,
     NoSFINAE;
+def err_access_ctor_vbase :
+    Error<"inherited virtual base class %0 has "
+    "%select{private|protected}1 constructor">,
+    NoSFINAE;
 def err_access_dtor_base :
     Error<"base class %0 has %select{private|protected}1 destructor">,
     NoSFINAE;

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Wed Apr 21 14:52:01 2010
@@ -1143,12 +1143,16 @@
     AccessEntity.setDiag(diag::err_access_ctor);
     break;
 
-  case InitializedEntity::EK_Base:
-    AccessEntity.setDiag(PDiag(diag::err_access_ctor_base)
+  case InitializedEntity::EK_Base: {
+    unsigned DiagID = Entity.isInheritedVirtualBase() ?
+      diag::err_access_ctor_vbase : diag::err_access_ctor_base;
+    AccessEntity.setDiag(PDiag(DiagID)
                           << Entity.getBaseSpecifier()->getType());
     break;
   }
 
+  }
+
   return CheckAccess(*this, UseLoc, AccessEntity);
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Apr 21 14:52:01 2010
@@ -1384,7 +1384,7 @@
 
   // Initialize the base.
   InitializedEntity BaseEntity =
-    InitializedEntity::InitializeBase(Context, BaseSpec);
+    InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
   InitializationKind Kind = 
     InitializationKind::CreateDirect(BaseLoc, LParenLoc, RParenLoc);
   
@@ -1435,9 +1435,11 @@
 static CXXBaseOrMemberInitializer *
 BuildImplicitBaseInitializer(Sema &SemaRef, 
                              const CXXConstructorDecl *Constructor,
-                             CXXBaseSpecifier *BaseSpec) {
+                             CXXBaseSpecifier *BaseSpec,
+                             bool IsInheritedVirtualBase) {
   InitializedEntity InitEntity
-    = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec);
+    = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
+                                        IsInheritedVirtualBase);
 
   InitializationKind InitKind
     = InitializationKind::CreateDefault(Constructor->getLocation());
@@ -1502,6 +1504,14 @@
       AllBaseFields[Member->getMember()] = Member;
   }
 
+  // Keep track of the direct virtual bases.
+  llvm::SmallPtrSet<CXXBaseSpecifier *, 16> DirectVBases;
+  for (CXXRecordDecl::base_class_iterator I = ClassDecl->bases_begin(),
+       E = ClassDecl->bases_end(); I != E; ++I) {
+    if (I->isVirtual())
+      DirectVBases.insert(I);
+  }
+
   // Push virtual bases before others.
   for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
        E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
@@ -1510,8 +1520,10 @@
         = AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
       AllToInit.push_back(Value);
     } else if (!AnyErrors) {
+      bool IsInheritedVirtualBase = !DirectVBases.count(VBase);
       CXXBaseOrMemberInitializer *CXXBaseInit =
-        BuildImplicitBaseInitializer(*this, Constructor, VBase);
+        BuildImplicitBaseInitializer(*this, Constructor, VBase,
+                                     IsInheritedVirtualBase);
 
       if (!CXXBaseInit) {
         HadError = true;
@@ -1533,8 +1545,9 @@
       AllToInit.push_back(Value);
     } else if (!AnyErrors) {
       CXXBaseOrMemberInitializer *CXXBaseInit =
-        BuildImplicitBaseInitializer(*this, Constructor, Base);
-      
+        BuildImplicitBaseInitializer(*this, Constructor, Base,
+                                     /*IsInheritedVirtualBase=*/false);
+
       if (!CXXBaseInit) {
         HadError = true;
         continue;

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Apr 21 14:52:01 2010
@@ -1921,11 +1921,15 @@
 }
 
 InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, 
-                                                    CXXBaseSpecifier *Base)
+                                                    CXXBaseSpecifier *Base,
+                                                    bool IsInheritedVirtualBase)
 {
   InitializedEntity Result;
   Result.Kind = EK_Base;
-  Result.Base = Base;
+  Result.Base = reinterpret_cast<uintptr_t>(Base);
+  if (IsInheritedVirtualBase)
+    Result.Base |= 0x01;
+  
   Result.Type = Base->getType();
   return Result;
 }

Modified: cfe/trunk/lib/Sema/SemaInit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.h?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.h (original)
+++ cfe/trunk/lib/Sema/SemaInit.h Wed Apr 21 14:52:01 2010
@@ -92,11 +92,12 @@
     unsigned Location;
     
     /// \brief When Kind == EK_Base, the base specifier that provides the 
-    /// base class.
-    CXXBaseSpecifier *Base;
+    /// base class. The lower bit specifies whether the base is an inherited
+    /// virtual base.
+    uintptr_t Base;
 
-    /// \brief When Kind = EK_ArrayElement or EK_VectorElement, the
-    /// index of the array or vector element being initialized.
+    /// \brief When Kind == EK_ArrayElement or EK_VectorElement, the
+    /// index of the array or vector element being initialized. 
     unsigned Index;
   };
 
@@ -168,7 +169,8 @@
   
   /// \brief Create the initialization entity for a base class subobject.
   static InitializedEntity InitializeBase(ASTContext &Context,
-                                          CXXBaseSpecifier *Base);
+                                          CXXBaseSpecifier *Base,
+                                          bool IsInheritedVirtualBase);
   
   /// \brief Create the initialization entity for a member subobject.
   static InitializedEntity InitializeMember(FieldDecl *Member,
@@ -204,7 +206,13 @@
   /// \brief Retrieve the base specifier.
   CXXBaseSpecifier *getBaseSpecifier() const {
     assert(getKind() == EK_Base && "Not a base specifier");
-    return Base;
+    return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1);
+  }
+
+  /// \brief Return whether the base is an inherited virtual base.
+  bool isInheritedVirtualBase() const {
+    assert(getKind() == EK_Base && "Not a base specifier");
+    return Base & 0x1;
   }
 
   /// \brief Determine the location of the 'return' keyword when initializing

Modified: cfe/trunk/test/CXX/class.access/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/p4.cpp?rev=102020&r1=102019&r2=102020&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/p4.cpp (original)
+++ cfe/trunk/test/CXX/class.access/p4.cpp Wed Apr 21 14:52:01 2010
@@ -103,9 +103,8 @@
   public:
     C();
   };
-  
-  // FIXME: It would be better if this said something about A being an inherited virtual base.
-  class D : C { }; // expected-error {{base class 'test2::A' has private constructor}}
+
+  class D : C { }; // expected-error {{inherited virtual base class 'test2::A' has private constructor}}
   D d;
 }
 





More information about the cfe-commits mailing list