Hi, I don't know if you've noticed, but this commit broke a lot of builds - e.g. http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15/builds/11865.
Regards, Diana On 28 April 2016 at 13:13, Denis Zobnin via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: dzobnin > Date: Thu Apr 28 05:13:18 2016 > New Revision: 267866 > > URL: http://llvm.org/viewvc/llvm-project?rev=267866&view=rev > Log: > [MS] Improved implementation of MS stack pragmas (vtordisp, *_seg) > > Rework implementation of several MS pragmas that use internal stack: > vtordisp, {bss|code|const|data}_seg. > This patch: > 1. Makes #pragma vtordisp use PragmaStack class as *_seg pragmas do; > 2. Fixes "#pragma vtordisp()" behavior: it shouldn't affect stack; > 3. Saves/restores the stacks on enter/exit a C++ method body. > > > Modified: > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Parse/ParsePragma.cpp > cfe/trunk/lib/Parse/ParseStmt.cpp > cfe/trunk/lib/Sema/Sema.cpp > cfe/trunk/lib/Sema/SemaAttr.cpp > cfe/trunk/test/CodeGenCXX/sections.cpp > cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Thu Apr 28 05:13:18 2016 > @@ -327,40 +327,21 @@ public: > LangOptions::PragmaMSPointersToMembersKind > MSPointerToMemberRepresentationMethod; > > - enum PragmaVtorDispKind { > - PVDK_Push, ///< #pragma vtordisp(push, mode) > - PVDK_Set, ///< #pragma vtordisp(mode) > - PVDK_Pop, ///< #pragma vtordisp(pop) > - PVDK_Reset ///< #pragma vtordisp() > - }; > - > - enum PragmaMsStackAction { > - PSK_Reset, // #pragma () > - PSK_Set, // #pragma ("name") > - PSK_Push, // #pragma (push[, id]) > - PSK_Push_Set, // #pragma (push[, id], "name") > - PSK_Pop, // #pragma (pop[, id]) > - PSK_Pop_Set, // #pragma (pop[, id], "name") > - }; > - > - /// \brief Whether to insert vtordisps prior to virtual bases in the > Microsoft > - /// C++ ABI. Possible values are 0, 1, and 2, which mean: > - /// > - /// 0: Suppress all vtordisps > - /// 1: Insert vtordisps in the presence of vbase overrides and > non-trivial > - /// structors > - /// 2: Always insert vtordisps to support RTTI on partially constructed > - /// objects > - /// > - /// The stack always has at least one element in it. > - SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; > - > /// Stack of active SEH __finally scopes. Can be empty. > SmallVector<Scope*, 2> CurrentSEHFinally; > > /// \brief Source location for newly created implicit MSInheritanceAttrs > SourceLocation ImplicitMSInheritanceAttrLoc; > > + enum PragmaMsStackAction { > + PSK_Reset = 0x0, // #pragma () > + PSK_Set = 0x1, // #pragma (value) > + PSK_Push = 0x2, // #pragma (push[, id]) > + PSK_Pop = 0x4, // #pragma (pop[, id]) > + PSK_Push_Set = PSK_Push | PSK_Set, // #pragma (push[, id], value) > + PSK_Pop_Set = PSK_Pop | PSK_Set, // #pragma (pop[, id], value) > + }; > + > template<typename ValueType> > struct PragmaStack { > struct Slot { > @@ -377,18 +358,84 @@ public: > PragmaMsStackAction Action, > llvm::StringRef StackSlotLabel, > ValueType Value); > - explicit PragmaStack(const ValueType &Value) > - : CurrentValue(Value) {} > + > + // MSVC seems to add artificial slots to #pragma stacks on entering a > C++ > + // method body to restore the stacks on exit, so it works like this: > + // > + // struct S { > + // #pragma <name>(push, InternalPragmaSlot, > <current_pragma_value>) > + // void Method {} > + // #pragma <name>(pop, InternalPragmaSlot) > + // }; > + // > + // It works even with #pragma vtordisp, although MSVC doesn't support > + // #pragma vtordisp(push [, id], n) > + // syntax. > + // > + // Push / pop a named sentinel slot. > + void SentinelAction(PragmaMsStackAction Action, StringRef Label) { > + assert((Action == PSK_Push || Action == PSK_Pop) && > + "Can only push / pop #pragma stack sentinels!"); > + Act(CurrentPragmaLocation, Action, Label, CurrentValue); > + } > + > + // Constructors. > + explicit PragmaStack(const ValueType &Default) > + : DefaultValue(Default), CurrentValue(Default) {} > + > SmallVector<Slot, 2> Stack; > + ValueType DefaultValue; // Value used for PSK_Reset action. > ValueType CurrentValue; > SourceLocation CurrentPragmaLocation; > }; > // FIXME: We should serialize / deserialize these if they occur in a > PCH (but > // we shouldn't do so if they're in a module). > + > + /// \brief Whether to insert vtordisps prior to virtual bases in the > Microsoft > + /// C++ ABI. Possible values are 0, 1, and 2, which mean: > + /// > + /// 0: Suppress all vtordisps > + /// 1: Insert vtordisps in the presence of vbase overrides and > non-trivial > + /// structors > + /// 2: Always insert vtordisps to support RTTI on partially constructed > + /// objects > + PragmaStack<MSVtorDispAttr::Mode> VtorDispStack; > PragmaStack<StringLiteral *> DataSegStack; > PragmaStack<StringLiteral *> BSSSegStack; > PragmaStack<StringLiteral *> ConstSegStack; > PragmaStack<StringLiteral *> CodeSegStack; > + // TODO: Change implementation of #pragma pack to use PragmaStack<> > approach. > + > + // RAII object to psuh / pop sentinel slots for all MS #pragma stacks. > + // Actions should be performed only if we enter / exit a C++ method > body. > + class PragmaStackSentinelRAII { > + public: > + 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); > + } > + } > + > + ~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); > + } > + } > + > + private: > + Sema &S; > + StringRef SlotLabel; > + bool ShouldAct; > + }; > > /// A mapping that describes the nullability we've seen in each header > file. > FileNullabilityMap NullabilityMap; > @@ -1011,24 +1058,6 @@ public: > bool OldFPContractState : 1; > }; > > - /// Records and restores the vtordisp state on entry/exit of C++ method > body. > - class VtorDispStackRAII { > - public: > - VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore) > - : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), > OldVtorDispStack() { > - if (ShouldSaveAndRestore) > - OldVtorDispStack = S.VtorDispModeStack; > - } > - ~VtorDispStackRAII() { > - if (ShouldSaveAndRestore) > - S.VtorDispModeStack = OldVtorDispStack; > - } > - private: > - Sema &S; > - bool ShouldSaveAndRestore; > - SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack; > - }; > - > void addImplicitTypedef(StringRef Name, QualType T); > > public: > @@ -7666,7 +7695,8 @@ public: > SourceLocation PragmaLoc); > > /// \brief Called on well formed \#pragma vtordisp(). > - void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation > PragmaLoc, > + void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, > + SourceLocation PragmaLoc, > MSVtorDispAttr::Mode Value); > > enum PragmaSectionKind { > > Modified: cfe/trunk/lib/Parse/ParsePragma.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParsePragma.cpp (original) > +++ cfe/trunk/lib/Parse/ParsePragma.cpp Thu Apr 28 05:13:18 2016 > @@ -497,11 +497,11 @@ void Parser::HandlePragmaMSPointersToMem > 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 @@ void PragmaMSVtorDisp::HandlePragma(Prep > } > 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 @@ void PragmaMSVtorDisp::HandlePragma(Prep > 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 @@ void PragmaMSVtorDisp::HandlePragma(Prep > 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); > } > > > Modified: cfe/trunk/lib/Parse/ParseStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseStmt.cpp (original) > +++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Apr 28 05:13:18 2016 > @@ -1928,7 +1928,8 @@ Decl *Parser::ParseFunctionStatementBody > // Save and reset current vtordisp stack if we have entered a C++ > method body. > bool IsCXXMethod = > getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl); > - Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod); > + Sema::PragmaStackSentinelRAII > + PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod); > > // Do not enter a scope for the brace, as the arguments are in the same > scope > // (the function body) as the body itself. Instead, just read the > statement > @@ -1972,7 +1973,8 @@ Decl *Parser::ParseFunctionTryBlock(Decl > // Save and reset current vtordisp stack if we have entered a C++ > method body. > bool IsCXXMethod = > getLangOpts().CPlusPlus && Decl && isa<CXXMethodDecl>(Decl); > - Sema::VtorDispStackRAII SavedVtorDispStack(Actions, IsCXXMethod); > + Sema::PragmaStackSentinelRAII > + PragmaStackSentinel(Actions, "InternalPragmaState", IsCXXMethod); > > SourceLocation LBraceLoc = Tok.getLocation(); > StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc, /*FnTry*/true)); > > Modified: cfe/trunk/lib/Sema/Sema.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.cpp (original) > +++ cfe/trunk/lib/Sema/Sema.cpp Thu Apr 28 05:13:18 2016 > @@ -82,7 +82,7 @@ Sema::Sema(Preprocessor &pp, ASTContext > PackContext(nullptr), MSStructPragmaOn(false), > MSPointerToMemberRepresentationMethod( > LangOpts.getMSPointerToMemberRepresentationMethod()), > - VtorDispModeStack(1, MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), > + VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), > DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr), > CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr), > IsBuildingRecoveryCallExpr(false), > > Modified: cfe/trunk/lib/Sema/SemaAttr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaAttr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu Apr 28 05:13:18 2016 > @@ -136,9 +136,9 @@ void Sema::AddMsStructLayoutForRecord(Re > // 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 +292,13 @@ void Sema::ActOnPragmaMSPointersToMember > 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 +307,7 @@ void Sema::PragmaStack<ValueType>::Act(S > llvm::StringRef StackSlotLabel, > ValueType Value) { > if (Action == PSK_Reset) { > - CurrentValue = nullptr; > + CurrentValue = DefaultValue; > return; > } > if (Action & PSK_Push) > > Modified: cfe/trunk/test/CodeGenCXX/sections.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sections.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/sections.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/sections.cpp Thu Apr 28 05:13:18 2016 > @@ -31,6 +31,31 @@ int TEST1; > #pragma bss_seg(pop) > int TEST2; > > + > +// Check "save-restore" of pragma stacks. > +struct Outer { > + void f() { > + #pragma bss_seg(push, ".bss3") > + #pragma code_seg(push, ".my_code1") > + #pragma const_seg(push, ".my_const1") > + #pragma data_seg(push, ".data3") > + struct Inner { > + void g() { > + #pragma bss_seg(push, ".bss4") > + #pragma code_seg(push, ".my_code2") > + #pragma const_seg(push, ".my_const2") > + #pragma data_seg(push, ".data4") > + } > + }; > + } > +}; > + > +void h2(void) {} // should be in ".my_code" > +int TEST3; // should be in ".bss1" > +int d2 = 1; // should be in ".data" > +extern const int b2; // should be in ".my_const" > +const int b2 = 1; > + > #pragma section("read_flag_section", read) > // Even though they are not declared const, these become constant since > they are > // in a read-only section. > @@ -63,6 +88,9 @@ __declspec(allocate("short_section")) sh > //CHECK: @i = global i32 0 > //CHECK: @TEST1 = global i32 0 > //CHECK: @TEST2 = global i32 0, section ".bss1" > +//CHECK: @TEST3 = global i32 0, section ".bss1" > +//CHECK: @d2 = global i32 1, section ".data" > +//CHECK: @b2 = constant i32 1, section ".my_const" > //CHECK: @unreferenced = constant i32 0, section "read_flag_section" > //CHECK: @referenced = constant i32 42, section "read_flag_section" > //CHECK: @implicitly_read_write = global i32 42, section > "no_section_attributes" > @@ -70,3 +98,4 @@ __declspec(allocate("short_section")) sh > //CHECK: @short_var = global i16 42, section "short_section" > //CHECK: define void @g() > //CHECK: define void @h() {{.*}} section ".my_code" > +//CHECK: define void @h2() {{.*}} section ".my_code" > > Modified: cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp?rev=267866&r1=267865&r2=267866&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp (original) > +++ cfe/trunk/test/SemaCXX/pragma-vtordisp.cpp Thu Apr 28 05:13:18 2016 > @@ -22,7 +22,8 @@ struct B : virtual A { int b; }; > > // Test a reset. > #pragma vtordisp() > -#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) > failed: stack empty}} > +#pragma vtordisp(pop) // stack should NOT be affected by reset. > + // Now stack contains '1'. > > #pragma vtordisp( // expected-warning {{unknown action for '#pragma > vtordisp' - ignored}} > #pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma > vtordisp' - ignored}} > @@ -42,6 +43,7 @@ struct E { > virtual void f(); > }; > > +#pragma vtordisp(pop) // After this stack should be empty. > #pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) > failed: stack empty}} > > void g() { > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits