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
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 2352fbe..adeac13 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -497,11 +497,11 @@
void Parser::HandlePragmaMSVtorDisp() {
assert(Tok.is(tok::annot_pragma_ms_vtordisp));
uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
- Sema::PragmaVtorDispKind Kind =
- static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
+ Sema::PragmaMsStackAction Action =
+ static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
- Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
+ Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
}
void Parser::HandlePragmaMSPragma() {
@@ -1606,7 +1606,7 @@
}
PP.Lex(Tok);
- Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
+ Sema::PragmaMsStackAction Action = Sema::PSK_Set;
const IdentifierInfo *II = Tok.getIdentifierInfo();
if (II) {
if (II->isStr("push")) {
@@ -1617,24 +1617,24 @@
return;
}
PP.Lex(Tok);
- Kind = Sema::PVDK_Push;
+ Action = Sema::PSK_Push_Set;
// not push, could be on/off
} else if (II->isStr("pop")) {
// #pragma vtordisp(pop)
PP.Lex(Tok);
- Kind = Sema::PVDK_Pop;
+ Action = Sema::PSK_Pop;
}
// not push or pop, could be on/off
} else {
if (Tok.is(tok::r_paren)) {
// #pragma vtordisp()
- Kind = Sema::PVDK_Reset;
+ Action = Sema::PSK_Reset;
}
}
uint64_t Value = 0;
- if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
+ if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
const IdentifierInfo *II = Tok.getIdentifierInfo();
if (II && II->isStr("off")) {
PP.Lex(Tok);
@@ -1676,7 +1676,7 @@
AnnotTok.setLocation(VtorDispLoc);
AnnotTok.setAnnotationEndLoc(EndLoc);
AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
- static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
+ static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
PP.EnterToken(AnnotTok);
}