diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-02-12 23:50:26 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-02-12 23:50:26 +0000 |
commit | c0dca6ded73199d6a111f8b785a3a0295eb57f31 (patch) | |
tree | 294643f74f87ab60896c5c94f4762019d298cf2a /clang/lib/AST/RecordLayoutBuilder.cpp | |
parent | c7d8885be4fe0479eda490d483059ca3dd46390a (diff) | |
download | bcm5719-llvm-c0dca6ded73199d6a111f8b785a3a0295eb57f31.tar.gz bcm5719-llvm-c0dca6ded73199d6a111f8b785a3a0295eb57f31.zip |
MS ABI: Implement #pragma vtordisp() and clang-cl /vdN
These features are new in VS 2013 and are necessary in order to layout
std::ostream correctly. Currently we have an ABI incompatibility when
self-hosting with the 2013 stdlib in our convertible_fwd_ostream wrapper
in gtest.
This change adds another implicit attribute, MSVtorDispAttr, because
implicit attributes are currently the best way to make sure the
information stays on class templates through instantiation.
Reviewers: majnemer
Differential Revision: http://llvm-reviews.chandlerc.com/D2746
llvm-svn: 201274
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 1f64b4be507..5624ce7836f 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2731,6 +2731,30 @@ RequiresVtordisp(const llvm::SmallPtrSet<const CXXRecordDecl *, 2> &HasVtordisp, llvm::SmallPtrSet<const CXXRecordDecl *, 2> MicrosoftRecordLayoutBuilder::computeVtorDispSet(const CXXRecordDecl *RD) { llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet; + + // /vd0 or #pragma vtordisp(0): Never use vtordisps when used as a vbase. + if (RD->getMSVtorDispMode() == MSVtorDispAttr::Never) + return HasVtordispSet; + + // /vd2 or #pragma vtordisp(2): Always use vtordisps for virtual bases with + // vftables. + if (RD->getMSVtorDispMode() == MSVtorDispAttr::ForVFTable) { + for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), + E = RD->vbases_end(); + I != E; ++I) { + const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); + const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); + if (Layout.hasExtendableVFPtr()) + HasVtordispSet.insert(BaseDecl); + } + return HasVtordispSet; + } + + // /vd1 or #pragma vtordisp(1): Try to guess based on whether we think it's + // possible for a partially constructed object with virtual base overrides to + // escape a non-trivial constructor. + assert(RD->getMSVtorDispMode() == MSVtorDispAttr::ForVBaseOverride); + // If any of our bases need a vtordisp for this type, so do we. Check our // direct bases for vtordisp requirements. for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), |