diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp | 275 |
1 files changed, 80 insertions, 195 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp index 5a29bad29f4..0d7fba5c670 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaAttr.cpp @@ -25,103 +25,37 @@ using namespace clang; // Pragma 'pack' and 'options align' //===----------------------------------------------------------------------===// -namespace { - struct PackStackEntry { - // We just use a sentinel to represent when the stack is set to mac68k - // alignment. - static const unsigned kMac68kAlignmentSentinel = ~0U; - - unsigned Alignment; - IdentifierInfo *Name; - }; - - /// PragmaPackStack - Simple class to wrap the stack used by #pragma - /// pack. - class PragmaPackStack { - typedef std::vector<PackStackEntry> stack_ty; - - /// Alignment - The current user specified alignment. - unsigned Alignment; - - /// Stack - Entries in the #pragma pack stack, consisting of saved - /// alignments and optional names. - stack_ty Stack; - - public: - PragmaPackStack() : Alignment(0) {} - - void setAlignment(unsigned A) { Alignment = A; } - unsigned getAlignment() { return Alignment; } - - /// push - Push the current alignment onto the stack, optionally - /// using the given \arg Name for the record, if non-zero. - void push(IdentifierInfo *Name) { - PackStackEntry PSE = { Alignment, Name }; - Stack.push_back(PSE); - } - - /// pop - Pop a record from the stack and restore the current - /// alignment to the previous value. If \arg Name is non-zero then - /// the first such named record is popped, otherwise the top record - /// is popped. Returns true if the pop succeeded. - bool pop(IdentifierInfo *Name, bool IsReset); - }; -} // end anonymous namespace. - -bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) { - // If name is empty just pop top. - if (!Name) { - // An empty stack is a special case... - if (Stack.empty()) { - // If this isn't a reset, it is always an error. - if (!IsReset) - return false; - - // Otherwise, it is an error only if some alignment has been set. - if (!Alignment) - return false; - - // Otherwise, reset to the default alignment. - Alignment = 0; - } else { - Alignment = Stack.back().Alignment; - Stack.pop_back(); - } - - return true; - } - - // Otherwise, find the named record. - for (unsigned i = Stack.size(); i != 0; ) { - --i; - if (Stack[i].Name == Name) { - // Found it, pop up to and including this record. - Alignment = Stack[i].Alignment; - Stack.erase(Stack.begin() + i, Stack.end()); - return true; - } +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); } - - return false; } - -/// FreePackedContext - Deallocate and null out PackContext. -void Sema::FreePackedContext() { - delete static_cast<PragmaPackStack*>(PackContext); - PackContext = nullptr; +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); + } } void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { - // If there is no pack context, we don't need any attributes. - if (!PackContext) + // If there is no pack value, we don't need any attributes. + if (!PackStack.CurrentValue) return; - PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext); - // Otherwise, check to see if we need a max field alignment attribute. - if (unsigned Alignment = Stack->getAlignment()) { - if (Alignment == PackStackEntry::kMac68kAlignmentSentinel) + if (unsigned Alignment = PackStack.CurrentValue) { + if (Alignment == Sema::kMac68kAlignmentSentinel) RD->addAttr(AlignMac68kAttr::CreateImplicit(Context)); else RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context, @@ -136,18 +70,15 @@ 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, SourceLocation PragmaLoc) { - if (!PackContext) - PackContext = new PragmaPackStack(); - - PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); - + PragmaMsStackAction Action = Sema::PSK_Reset; + unsigned Alignment = 0; switch (Kind) { // For all targets we support native and natural are the same. // @@ -155,15 +86,15 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, case POAK_Native: case POAK_Power: case POAK_Natural: - Context->push(nullptr); - Context->setAlignment(0); + Action = Sema::PSK_Push_Set; + Alignment = 0; break; // Note that '#pragma options align=packed' is not equivalent to attribute // packed, it has a different precedence relative to attribute aligned. case POAK_Packed: - Context->push(nullptr); - Context->setAlignment(1); + Action = Sema::PSK_Push_Set; + Alignment = 1; break; case POAK_Mac68k: @@ -172,24 +103,31 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); return; } - Context->push(nullptr); - Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel); + Action = Sema::PSK_Push_Set; + Alignment = Sema::kMac68kAlignmentSentinel; break; case POAK_Reset: // Reset just pops the top of the stack, or resets the current alignment to // default. - if (!Context->pop(nullptr, /*IsReset=*/true)) { - Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) - << "stack empty"; + Action = Sema::PSK_Pop; + if (PackStack.Stack.empty()) { + if (PackStack.CurrentValue) { + Action = Sema::PSK_Reset; + } else { + Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) + << "stack empty"; + return; + } } break; } + + PackStack.Act(PragmaLoc, Action, StringRef(), Alignment); } -void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, - Expr *alignment, SourceLocation PragmaLoc, - SourceLocation LParenLoc, SourceLocation RParenLoc) { +void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, + StringRef SlotLabel, Expr *alignment) { Expr *Alignment = static_cast<Expr *>(alignment); // If specified then alignment must be a "small" power of two. @@ -210,87 +148,48 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, AlignmentVal = (unsigned) Val.getZExtValue(); } - - if (!PackContext) - PackContext = new PragmaPackStack(); - - PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); - - switch (Kind) { - case Sema::PPK_Default: // pack([n]) - Context->setAlignment(AlignmentVal); - break; - - case Sema::PPK_Show: // pack(show) + if (Action == Sema::PSK_Show) { // Show the current alignment, making sure to show the right value // for the default. - AlignmentVal = Context->getAlignment(); // FIXME: This should come from the target. + AlignmentVal = PackStack.CurrentValue; if (AlignmentVal == 0) AlignmentVal = 8; - if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel) + if (AlignmentVal == Sema::kMac68kAlignmentSentinel) Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; else Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; - break; - - case Sema::PPK_Push: // pack(push [, id] [, [n]) - Context->push(Name); - // Set the new alignment if specified. - if (Alignment) - Context->setAlignment(AlignmentVal); - break; - - case Sema::PPK_Pop: // pack(pop [, id] [, n]) - // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: - // "#pragma pack(pop, identifier, n) is undefined" - if (Alignment && Name) + } + // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: + // "#pragma pack(pop, identifier, n) is undefined" + if (Action & Sema::PSK_Pop) { + if (Alignment && !SlotLabel.empty()) Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); - - // Do the pop. - if (!Context->pop(Name, /*IsReset=*/false)) { - // 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_pop_failed) - << "pack" << (Name ? "no record matching name" : "stack empty"); - - // FIXME: Warn about popping named records as MSVC does. - } else { - // Pop succeeded, set the new alignment if specified. - if (Alignment) - Context->setAlignment(AlignmentVal); - } - break; + if (PackStack.Stack.empty()) + Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty"; } + + PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal); } void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { MSStructPragmaOn = (Kind == PMSST_ON); } -void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) { - // FIXME: Serialize this. - switch (Kind) { - case PCK_Unknown: - llvm_unreachable("unexpected pragma comment kind"); - case PCK_Linker: - Consumer.HandleLinkerOptionPragma(Arg); - return; - case PCK_Lib: - Consumer.HandleDependentLibrary(Arg); - return; - case PCK_Compiler: - case PCK_ExeStr: - case PCK_User: - return; // We ignore all of these. - } - llvm_unreachable("invalid pragma comment kind"); +void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc, + PragmaMSCommentKind Kind, StringRef Arg) { + auto *PCD = PragmaCommentDecl::Create( + Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg); + Context.getTranslationUnitDecl()->addDecl(PCD); + Consumer.HandleTopLevelDecl(DeclGroupRef(PCD)); } -void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) { - // FIXME: Serialize this. - Consumer.HandleDetectMismatch(Name, Value); +void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, + StringRef Value) { + auto *PDMD = PragmaDetectMismatchDecl::Create( + Context, Context.getTranslationUnitDecl(), Loc, Name, Value); + Context.getTranslationUnitDecl()->addDecl(PDMD); + Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); } void Sema::ActOnPragmaMSPointersToMembers( @@ -300,29 +199,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> @@ -331,7 +214,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) @@ -339,8 +222,9 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation, else if (Action & PSK_Pop) { if (!StackSlotLabel.empty()) { // If we've got a label, try to find it and jump there. - auto I = std::find_if(Stack.rbegin(), Stack.rend(), - [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; }); + auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { + return x.StackSlotLabel == StackSlotLabel; + }); // If we found the label so pop from there. if (I != Stack.rend()) { CurrentValue = I->Value; @@ -467,7 +351,8 @@ void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, if (VD->isUsed()) Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; - VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation())); + VD->addAttr(UnusedAttr::CreateImplicit(Context, UnusedAttr::GNU_unused, + IdTok.getLocation())); } void Sema::AddCFAuditedAttribute(Decl *D) { |
