[cfe-dev] Microsoft vtordisp field support for clang.
r4start
r4start at gmail.com
Thu Feb 16 04:43:20 PST 2012
On 15/02/2012 23:28, John McCall wrote:
> On Feb 15, 2012, at 4:37 AM, r4start wrote:
>> Please see this patch.
> You don't need the store both the set of vbases with vtordisps and the
> additional information in the virtual-base-offset map. I would prefer that
> you rely only on the second; it has the distinct virtual of imposing no
> extra overload to the layouts of classes without virtual bases.
>
>> I am not sure that new algorithm very efficient, but I think new algorithm is better than old one.
> Why is this influenced by whether the class has a new virtual function?
This check need if we have something like this:
class first{
public:
virtual void asdf() {}
virtual void g(){}
};
class second : public virtual first {
public :
second(){}
virtual void g(){}
virtual void asdf() {}
};
class third : public virtual second {
public:
third(){}
virtual void g() {}
virtual void asdf() {}
};
Only first will have vtordisp. Also flags in condition help to ignore
this check in next case:
struct AV {
virtual void foo();
};
struct BV : AV {
};
struct C : virtual BV {
C();
virtual void foo();
};
> Here's my suggested (untested) implementation:
>
> void RecordLayoutBuilder::getRequiredVtorDisps(const CXXRecordDecl *RD, llvm::SmallPtrSet<const CXXRecordDecl*> &VBasesRequiringVtorDisp) {
> if (RD->vbases_empty()) return;
>
> // As an optimization, remember the set of virtual bases that we haven't decided yet.
> llvm::SmallPtrSet<const CXXRecordDecl *> UndecidedVBases;
> for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
> E = RD->vbases_end(); I != E; ++I) {
> UndecidedVBases.insert(*I);
> }
>
> // A virtual base requires a vtor disp if any of our base classes require it to have one.
> for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
> E = RD->bases_end(); I != E; ++I) {
> const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
> const ASTRecordLayout&BaseLayout = Context.getASTRecordLayout(BaseDecl);
> for (ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
> VI = BaseLayout.VBaseOffsetsMap.begin(), VE = BaseLayout.VBaseOffsetsMap.end(); VI != VE; ++VI) {
> if (!VI->second.IsVtorDispPresent) continue;
> if (!UndecidedVBases.erase(VI->first)) continue;
> VBasesRequiringVtorDisp.insert(VI->first);
> if (UndecidedVBases.empty()) return;
> }
> }
>
> // Otherwise, a virtual base requires a vtor disp if any the non-destructor
> // virtual methods declared in this class directly override a method provided
> // by that virtual base.
>
> // Collect the set of bases directly overridden by any method in this class.
> // It's possible that some of these classes won't be virtual bases, or won't be
> // provided by virtual bases, or won't be virtual bases in the overridden
> // instance but are virtual bases elsewhere. Only the last matters for what
> // we're doing, and we can ignore those: if we don't directly override
> // a method provided by a virtual copy of a base class, but we do directly
> // override a method provided by a non-virtual copy of that base class,
> // then we must indirectly override the method provided by the virtual base,
> // and so we should already have collected it in the loop above.
> llvm::SmallPtrSet<const CXXRecordDecl*> OverriddenBases;
> for (CXXRecordDecl::method_iterator M = RD->method_begin(),
> E = RD->method_end(); M != E; ++M) {
> if (!M->isVirtual() || isa<CXXDestructorDecl>(M)) continue;
> for (CXXMethodDecl::method_iterator I = M->begin_overridden_methods(),
> E = M->end_overridden_methods(); I != E; ++I) {
> const CXXRecordDecl *OverriddenBase = (*I)->getParent();
>
> // As an optimization, check immediately whether we're overriding
> // something from the undecided set.
> if (UndecidedVBases.erase(OverriddenBase)) {
> VBasesRequiringVtorDisp.insert(OverriddenBase);
> if (UndecidedVBases.empty()) return;
> continue;
> }
>
> // Otherwise, just collect it.
> OverriddenBases.insert(OverriddenBase);
> }
> }
>
> // Walk the undecided v-bases and check whether they (non-virtually)
> // provide any of the overridden bases.
> for (llvm::SmallPtrSet<const CXXRecordDecl*>::const_iterator
> I = UndecidedVBases.begin(), E = UndecidedVBases.end(); I != E; ++I) {
> if (hasAnyNonVirtualBase(*I, OverriddenBases))
> VBasesRequiringVtorDisp.insert(*I);
> }
> }
>
> Where hasAnyNonVirtualBase just recursively walks the non-virtual
> class hierarchy and checks whether any of the bases are in the set.
>
Thx for your algorithm, it works fine in general. I add one condition
and write hasAnyNonVirtualBase.
If realization is ok, then I cleanup code and relocate it to ToT.
Also I include patch for condition in Layout function, this patch must
be committed before vtordisp patch.
- Dmitry.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ms-layout.patch
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120216/fb9980bb/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: new-vtordisp.patch
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120216/fb9980bb/attachment-0001.ksh>
More information about the cfe-dev
mailing list