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/Sema/SemaAttr.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/Sema/SemaAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 4da14ec1d1d..6c6ba18018f 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -130,9 +130,15 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { } void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { - if (!MSStructPragmaOn) - return; - RD->addAttr(MsStructAttr::CreateImplicit(Context)); + if (MSStructPragmaOn) + RD->addAttr(MsStructAttr::CreateImplicit(Context)); + + // FIXME: We should merge AddAlignmentAttributesForRecord with + // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes + // all active pragmas and applies them as attributes to class definitions. + if (VtorDispModeStack.back() != getLangOpts().VtorDispMode) + RD->addAttr( + MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back())); } void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, @@ -246,8 +252,8 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, // If a name was specified then failure indicates the name // wasn't found. Otherwise failure indicates the stack was // empty. - Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed) - << (Name ? "no record matching name" : "stack empty"); + Diag(PragmaLoc, diag::warn_pragma_pop_failed) + << "pack" << (Name ? "no record matching name" : "stack empty"); // FIXME: Warn about popping named records as MSVC does. } else { @@ -294,6 +300,31 @@ void Sema::ActOnPragmaMSPointersToMembers( ImplicitMSInheritanceAttrLoc = PragmaLoc; } +void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, + SourceLocation PragmaLoc, + MSVtorDispAttr::Mode Mode) { + switch (Kind) { + case PVDK_Set: + VtorDispModeStack.back() = Mode; + break; + case PVDK_Push: + VtorDispModeStack.push_back(Mode); + break; + case PVDK_Reset: + VtorDispModeStack.clear(); + VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)); + break; + case PVDK_Pop: + VtorDispModeStack.pop_back(); + if (VtorDispModeStack.empty()) { + Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" + << "stack empty"; + VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)); + } + break; + } +} + void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, SourceLocation PragmaLoc) { |