diff options
author | Denis Zobnin <d.zobnin.bugzilla@gmail.com> | 2016-04-29 11:27:00 +0000 |
---|---|---|
committer | Denis Zobnin <d.zobnin.bugzilla@gmail.com> | 2016-04-29 11:27:00 +0000 |
commit | 2290dacaf894f26ac6a5058ec2cf438af87a6c96 (patch) | |
tree | 2e160cd6fe87f1dae81e5f7224c7c7044126437e /clang/lib/Sema/SemaAttr.cpp | |
parent | 0b9d105a1607fc0b1eebc25ddd06f5b5162fff5d (diff) | |
download | bcm5719-llvm-2290dacaf894f26ac6a5058ec2cf438af87a6c96.tar.gz bcm5719-llvm-2290dacaf894f26ac6a5058ec2cf438af87a6c96.zip |
Recommit "[MS] Improved implementation of stack pragmas (vtordisp, *_seg)"
Slightly updated version, double-checked build and tests.
Improve implementation of MS pragmas that use stack + compatibility fixes.
This patch:
1. Changes implementation of #pragma vtordisp to use PragmaStack class
that other stack pragmas use;
2. Fixes "#pragma vtordisp()" behavior - it shouldn't affect the stack;
3. Supports "save-restore" of pragma stacks on enter / exit a C++ method
body, as MSVC does.
TODO:
1. Change implementation of #pragma pack to use the same approach;
2. Introduce diagnostics on popping named stack slots, as MSVC does.
Reviewers:
rnk, thakis
Differential revision: http://reviews.llvm.org/D19361
llvm-svn: 268029
Diffstat (limited to 'clang/lib/Sema/SemaAttr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 7f523c465af..c22c7c620c9 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -105,6 +105,28 @@ bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) { return false; } +Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S, + StringRef SlotLabel, + bool ShouldAct) + : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) { + if (ShouldAct) { + S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel); + S.DataSegStack.SentinelAction(PSK_Push, SlotLabel); + S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel); + S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel); + S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel); + } +} + +Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() { + if (ShouldAct) { + S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel); + S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel); + S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel); + S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel); + S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel); + } +} /// FreePackedContext - Deallocate and null out PackContext. void Sema::FreePackedContext() { @@ -136,9 +158,9 @@ void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { // 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) + if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode) RD->addAttr( - MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back())); + MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue)); } void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, @@ -292,29 +314,13 @@ void Sema::ActOnPragmaMSPointersToMembers( ImplicitMSInheritanceAttrLoc = PragmaLoc; } -void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, +void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, 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; - } + if (Action & PSK_Pop && VtorDispStack.Stack.empty()) + Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" + << "stack empty"; + VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); } template<typename ValueType> @@ -323,7 +329,7 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation, llvm::StringRef StackSlotLabel, ValueType Value) { if (Action == PSK_Reset) { - CurrentValue = nullptr; + CurrentValue = DefaultValue; return; } if (Action & PSK_Push) |