[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