1ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===// 25a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 35a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// The LLVM Compiler Infrastructure 45a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 55a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// This file is distributed under the University of Illinois Open Source 65a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// License. See LICENSE.TXT for details. 75a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 85a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===----------------------------------------------------------------------===// 95a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 10574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner// This file implements semantic analysis for non-trivial attributes and 11574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner// pragmas. 125a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner// 135a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===----------------------------------------------------------------------===// 145a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 152d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 163190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner#include "clang/AST/ASTConsumer.h" 17cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt#include "clang/AST/Attr.h" 185a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner#include "clang/AST/Expr.h" 19613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar#include "clang/Basic/TargetInfo.h" 20613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar#include "clang/Lex/Preprocessor.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Lookup.h" 225a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattnerusing namespace clang; 235a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 24574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 25ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar// Pragma 'pack' and 'options align' 26574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 27574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 28574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnernamespace { 29ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar struct PackStackEntry { 30c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // We just use a sentinel to represent when the stack is set to mac68k 31c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // alignment. 32c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar static const unsigned kMac68kAlignmentSentinel = ~0U; 33c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 34ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar unsigned Alignment; 35ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar IdentifierInfo *Name; 36ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar }; 37ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar 38574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// PragmaPackStack - Simple class to wrap the stack used by #pragma 39574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pack. 40574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner class PragmaPackStack { 41ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar typedef std::vector<PackStackEntry> stack_ty; 42574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 43574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Alignment - The current user specified alignment. 44574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned Alignment; 45574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 46574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Stack - Entries in the #pragma pack stack, consisting of saved 47574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignments and optional names. 48574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner stack_ty Stack; 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump public: 51574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack() : Alignment(0) {} 52574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 53574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void setAlignment(unsigned A) { Alignment = A; } 54574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned getAlignment() { return Alignment; } 55574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 56574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// push - Push the current alignment onto the stack, optionally 57574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// using the given \arg Name for the record, if non-zero. 58574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void push(IdentifierInfo *Name) { 59ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar PackStackEntry PSE = { Alignment, Name }; 60ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar Stack.push_back(PSE); 61574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 62574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 63574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pop - Pop a record from the stack and restore the current 64574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignment to the previous value. If \arg Name is non-zero then 65574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// the first such named record is popped, otherwise the top record 66574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// is popped. Returns true if the pop succeeded. 67ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar bool pop(IdentifierInfo *Name, bool IsReset); 68574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner }; 69574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} // end anonymous namespace. 70574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 71ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbarbool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) { 72574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // If name is empty just pop top. 73574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (!Name) { 74ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // An empty stack is a special case... 75ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (Stack.empty()) { 76ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // If this isn't a reset, it is always an error. 77ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!IsReset) 78ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar return false; 79ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 80ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // Otherwise, it is an error only if some alignment has been set. 81ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!Alignment) 82ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar return false; 83ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 84ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // Otherwise, reset to the default alignment. 85ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Alignment = 0; 86ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar } else { 87ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Alignment = Stack.back().Alignment; 88ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Stack.pop_back(); 89ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar } 90ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 91574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 94574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Otherwise, find the named record. 95574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner for (unsigned i = Stack.size(); i != 0; ) { 96574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner --i; 97ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar if (Stack[i].Name == Name) { 98574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Found it, pop up to and including this record. 99ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar Alignment = Stack[i].Alignment; 100574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Stack.erase(Stack.begin() + i, Stack.end()); 101574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 102574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 103574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 105574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return false; 106574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 107574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 108574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 109574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner/// FreePackedContext - Deallocate and null out PackContext. 110574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnervoid Sema::FreePackedContext() { 111574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner delete static_cast<PragmaPackStack*>(PackContext); 1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PackContext = nullptr; 113574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 114574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 1159f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbarvoid Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 1169f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar // If there is no pack context, we don't need any attributes. 1179f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar if (!PackContext) 1189f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar return; 1199f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar 1209f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext); 1219f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar 1229f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar // Otherwise, check to see if we need a max field alignment attribute. 123c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (unsigned Alignment = Stack->getAlignment()) { 124c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (Alignment == PackStackEntry::kMac68kAlignmentSentinel) 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RD->addAttr(AlignMac68kAttr::CreateImplicit(Context)); 126c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar else 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context, 128cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Alignment * 8)); 129c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 130574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 131574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 132c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanianvoid Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MSStructPragmaOn) 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RD->addAttr(MsStructAttr::CreateImplicit(Context)); 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: We should merge AddAlignmentAttributesForRecord with 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // all active pragmas and applies them as attributes to class definitions. 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VtorDispModeStack.back() != getLangOpts().VtorDispMode) 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines RD->addAttr( 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back())); 142c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 143c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 144ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbarvoid Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 1459595c7e2533c836537dc300e75d059c29feb7094Eli Friedman SourceLocation PragmaLoc) { 1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!PackContext) 147ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar PackContext = new PragmaPackStack(); 148ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 149ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 150ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 151ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar switch (Kind) { 152638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // For all targets we support native and natural are the same. 153638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // 154638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // FIXME: This is not true on Darwin/PPC. 155638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar case POAK_Native: 156450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar case POAK_Power: 157d6b305dcba95fc4928a2baa6bbeb15d22db9d061Daniel Dunbar case POAK_Natural: 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context->push(nullptr); 159450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar Context->setAlignment(0); 160450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar break; 161450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar 1626f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar // Note that '#pragma options align=packed' is not equivalent to attribute 1636f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar // packed, it has a different precedence relative to attribute aligned. 1646f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar case POAK_Packed: 1656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context->push(nullptr); 1666f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar Context->setAlignment(1); 1676f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar break; 1686f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar 169613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar case POAK_Mac68k: 170613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar // Check if the target supports this. 1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) { 172613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 173613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar return; 174613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar } 1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Context->push(nullptr); 176c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel); 177613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar break; 178613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar 1799595c7e2533c836537dc300e75d059c29feb7094Eli Friedman case POAK_Reset: 1809595c7e2533c836537dc300e75d059c29feb7094Eli Friedman // Reset just pops the top of the stack, or resets the current alignment to 1819595c7e2533c836537dc300e75d059c29feb7094Eli Friedman // default. 1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Context->pop(nullptr, /*IsReset=*/true)) { 1839595c7e2533c836537dc300e75d059c29feb7094Eli Friedman Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 1849595c7e2533c836537dc300e75d059c29feb7094Eli Friedman << "stack empty"; 1859595c7e2533c836537dc300e75d059c29feb7094Eli Friedman } 186ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar break; 187ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar } 188ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar} 189ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, 191f81e5a9e3f3ff80c56e4afb4fe6311a8735f36e8Richard Trieu Expr *alignment, SourceLocation PragmaLoc, 1925a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner SourceLocation LParenLoc, SourceLocation RParenLoc) { 1935a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Expr *Alignment = static_cast<Expr *>(alignment); 1945a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1955a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If specified then alignment must be a "small" power of two. 1965a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner unsigned AlignmentVal = 0; 1975a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) { 1985a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner llvm::APSInt Val; 1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20079cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // pack(0) is like pack(), which just works out since that is what 20179cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // we use 0 for in PackAttr. 202ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Alignment->isTypeDependent() || 203ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor Alignment->isValueDependent() || 204ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Alignment->isIntegerConstantExpr(Val, Context) || 20579cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar !(Val == 0 || Val.isPowerOf2()) || 2065a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Val.getZExtValue() > 16) { 2075a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 2085a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner return; // Ignore 2095a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2105a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 2115a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = (unsigned) Val.getZExtValue(); 2125a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!PackContext) 215574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PackContext = new PragmaPackStack(); 2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 217574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2195a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner switch (Kind) { 220f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Default: // pack([n]) 221574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 2225a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2235a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 224f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Show: // pack(show) 2255a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Show the current alignment, making sure to show the right value 2265a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // for the default. 227574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner AlignmentVal = Context->getAlignment(); 2285a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: This should come from the target. 2295a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (AlignmentVal == 0) 2305a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = 8; 231c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel) 232c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; 233c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar else 234c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 2355a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2365a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 237f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Push: // pack(push [, id] [, [n]) 238574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->push(Name); 2395a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Set the new alignment if specified. 2405a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Context->setAlignment(AlignmentVal); 2425a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2435a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 244f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Pop: // pack(pop [, id] [, n]) 2455a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 2465a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // "#pragma pack(pop, identifier, n) is undefined" 2475a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment && Name) 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); 2491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2505a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Do the pop. 251ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!Context->pop(Name, /*IsReset=*/false)) { 2525a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If a name was specified then failure indicates the name 2535a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // wasn't found. Otherwise failure indicates the stack was 2545a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // empty. 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(PragmaLoc, diag::warn_pragma_pop_failed) 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << "pack" << (Name ? "no record matching name" : "stack empty"); 2575a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 2585a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: Warn about popping named records as MSVC does. 2595a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } else { 2605a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Pop succeeded, set the new alignment if specified. 2615a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 262574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 2635a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2645a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2655a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2665a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner} 2675a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 26862c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanianvoid Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 26962c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian MSStructPragmaOn = (Kind == PMSST_ON); 27062c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian} 27162c9258f4a71569a66d805fc7776526a2c76b34eFariborz Jahanian 27230d237556fdd29b5075c990da953116225b95d9dRobert Wilhelmvoid Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) { 2733190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner // FIXME: Serialize this. 2743190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner switch (Kind) { 2753190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner case PCK_Unknown: 2763190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner llvm_unreachable("unexpected pragma comment kind"); 2773190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner case PCK_Linker: 2783190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner Consumer.HandleLinkerOptionPragma(Arg); 2793190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner return; 28089735b9516b1a378c6d33620a6c3a0d5705f9d04Aaron Ballman case PCK_Lib: 2813190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner Consumer.HandleDependentLibrary(Arg); 2823190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner return; 2833190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner case PCK_Compiler: 2843190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner case PCK_ExeStr: 2853190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner case PCK_User: 2863190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner return; // We ignore all of these. 2873190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner } 2883190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner llvm_unreachable("invalid pragma comment kind"); 2893190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner} 2903190ca922d3743137e15fe0c525c04b177b9983bReid Kleckner 29130d237556fdd29b5075c990da953116225b95d9dRobert Wilhelmvoid Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) { 292a7ff62f9443efa3b13a28a1e566d4625b15b8553Aaron Ballman // FIXME: Serialize this. 293a7ff62f9443efa3b13a28a1e566d4625b15b8553Aaron Ballman Consumer.HandleDetectMismatch(Name, Value); 294a7ff62f9443efa3b13a28a1e566d4625b15b8553Aaron Ballman} 295a7ff62f9443efa3b13a28a1e566d4625b15b8553Aaron Ballman 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::ActOnPragmaMSPointersToMembers( 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines LangOptions::PragmaMSPointersToMembersKind RepresentationMethod, 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation PragmaLoc) { 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSPointerToMemberRepresentationMethod = RepresentationMethod; 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ImplicitMSInheritanceAttrLoc = PragmaLoc; 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLocation PragmaLoc, 305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines MSVtorDispAttr::Mode Mode) { 306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines switch (Kind) { 307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case PVDK_Set: 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.back() = Mode; 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case PVDK_Push: 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.push_back(Mode); 312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case PVDK_Reset: 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.clear(); 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)); 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case PVDK_Pop: 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.pop_back(); 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VtorDispModeStack.empty()) { 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines << "stack empty"; 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)); 323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines break; 325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinestemplate<typename ValueType> 3296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation, 3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PragmaMsStackAction Action, 3316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::StringRef StackSlotLabel, 3326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ValueType Value) { 3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Action == PSK_Reset) { 3346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentValue = nullptr; 3356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 3366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Action & PSK_Push) 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation)); 3396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (Action & PSK_Pop) { 3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!StackSlotLabel.empty()) { 3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If we've got a label, try to find it and jump there. 3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto I = std::find_if(Stack.rbegin(), Stack.rend(), 3436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; }); 3446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If we found the label so pop from there. 3456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (I != Stack.rend()) { 3466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentValue = I->Value; 3476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentPragmaLocation = I->PragmaLocation; 3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Stack.erase(std::prev(I.base()), Stack.end()); 3496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (!Stack.empty()) { 3516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // We don't have a label, just pop the last entry. 3526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentValue = Stack.back().Value; 3536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentPragmaLocation = Stack.back().PragmaLocation; 3546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Stack.pop_back(); 3556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Action & PSK_Set) { 3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentValue = Value; 3596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CurrentPragmaLocation = PragmaLocation; 3606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool Sema::UnifySection(const StringRef &SectionName, 3646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines int SectionFlags, 3656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines DeclaratorDecl *Decl) { 3666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto Section = SectionInfos.find(SectionName); 3676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Section == SectionInfos.end()) { 3686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SectionInfos[SectionName] = 3696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SectionInfo(Decl, SourceLocation(), SectionFlags); 3706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 3716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // A pre-declared section takes precedence w/o diagnostic. 3736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Section->second.SectionFlags == SectionFlags || 3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !(Section->second.SectionFlags & PSF_Implicit)) 3756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 3766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto OtherDecl = Section->second.Decl; 3776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(Decl->getLocation(), diag::err_section_conflict) 3786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << Decl << OtherDecl; 3796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(OtherDecl->getLocation(), diag::note_declared_at) 3806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << OtherDecl->getName(); 3816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (auto A = Decl->getAttr<SectionAttr>()) 3826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (A->isImplicit()) 3836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(A->getLocation(), diag::note_pragma_entered_here); 3846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (auto A = OtherDecl->getAttr<SectionAttr>()) 3856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (A->isImplicit()) 3866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(A->getLocation(), diag::note_pragma_entered_here); 3876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 3886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 3896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesbool Sema::UnifySection(const StringRef &SectionName, 3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines int SectionFlags, 3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation PragmaSectionLocation) { 3936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines auto Section = SectionInfos.find(SectionName); 3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Section != SectionInfos.end()) { 3956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Section->second.SectionFlags == SectionFlags) 3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 3976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!(Section->second.SectionFlags & PSF_Implicit)) { 3986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(PragmaSectionLocation, diag::err_section_conflict) 3996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << "this" << "a prior #pragma section"; 4006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(Section->second.PragmaSectionLocation, 4016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines diag::note_pragma_entered_here); 4026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 4036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SectionInfos[SectionName] = 4066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SectionInfo(nullptr, PragmaSectionLocation, SectionFlags); 4076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 4086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Called on well formed \#pragma bss_seg(). 4116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, 4126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PragmaMsStackAction Action, 4136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::StringRef StackSlotLabel, 4146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines StringLiteral *SegmentName, 4156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::StringRef PragmaName) { 4166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PragmaStack<StringLiteral *> *Stack = 4176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName) 4186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines .Case("data_seg", &DataSegStack) 4196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines .Case("bss_seg", &BSSSegStack) 4206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines .Case("const_seg", &ConstSegStack) 4216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines .Case("code_seg", &CodeSegStack); 4226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Action & PSK_Pop && Stack->Stack.empty()) 4236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName 4246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << "stack empty"; 4256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); 4266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines/// \brief Called on well formed \#pragma bss_seg(). 4296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation, 4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines int SectionFlags, StringLiteral *SegmentName) { 4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation); 4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 434b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisvoid Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 435b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis SourceLocation PragmaLoc) { 4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 437b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis IdentifierInfo *Name = IdTok.getIdentifierInfo(); 438b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 4396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LookupParsedName(Lookup, curScope, nullptr, true); 4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 441b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis if (Lookup.empty()) { 442b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 443b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis << Name << SourceRange(IdTok.getLocation()); 444b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis return; 445b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis } 4462127eccbe15fd3b1b29aa53ccedd2e0f55ad27f9Anders Carlsson 447b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 4482a5c45b1ae4406459fbb39cb477951987c59cb0fArgyrios Kyrtzidis if (!VD) { 4492a5c45b1ae4406459fbb39cb477951987c59cb0fArgyrios Kyrtzidis Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 450b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis << Name << SourceRange(IdTok.getLocation()); 451b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis return; 4524726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek } 453b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis 454b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis // Warn if this was used before being marked unused. 455b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis if (VD->isUsed()) 456b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 457b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation())); 4594726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek} 460aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 4618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallvoid Sema::AddCFAuditedAttribute(Decl *D) { 4628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc(); 4638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!Loc.isValid()) return; 4648dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 4658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Don't add a redundant or conflicting attribute. 4668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (D->hasAttr<CFAuditedTransferAttr>() || 4678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->hasAttr<CFUnknownTransferAttr>()) 4688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 4698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc)); 4718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 4728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 4736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) { 4746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if(On) 4756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OptimizeOffPragmaLocation = SourceLocation(); 4766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 4776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OptimizeOffPragmaLocation = PragmaLoc; 4786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::AddRangeBasedOptnone(FunctionDecl *FD) { 4816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // In the future, check other pragmas if they're implemented (e.g. pragma 4826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // optimize 0 will probably map to this functionality too). 4836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if(OptimizeOffPragmaLocation.isValid()) 4846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation); 4856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 4866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 4886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation Loc) { 4896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Don't add a conflicting attribute. No diagnostic is needed. 4906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>()) 4916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 4926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Add attributes only if required. Optnone requires noinline as well, but if 4946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // either is already present then don't bother adding them. 4956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FD->hasAttr<OptimizeNoneAttr>()) 4966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc)); 4976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!FD->hasAttr<NoInlineAttr>()) 4986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc)); 4996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 5006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 50190f1450c109fbbd333001165bbd986061f7c4513John McCalltypedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesenum : unsigned { NoVisibility = ~0U }; 503aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 504aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::AddPushedVisibilityAttribute(Decl *D) { 505aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (!VisContext) 506aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 507aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 508140aadf5b927ae294388c680a7db44e5de39578aRafael Espindola NamedDecl *ND = dyn_cast<NamedDecl>(D); 509d4c3d66be70ae2d0bd828329022dc428cc277a1cJohn McCall if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) 510aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 511aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 512aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman VisStack *Stack = static_cast<VisStack*>(VisContext); 51390f1450c109fbbd333001165bbd986061f7c4513John McCall unsigned rawType = Stack->back().first; 51490f1450c109fbbd333001165bbd986061f7c4513John McCall if (rawType == NoVisibility) return; 51590f1450c109fbbd333001165bbd986061f7c4513John McCall 51690f1450c109fbbd333001165bbd986061f7c4513John McCall VisibilityAttr::VisibilityType type 51790f1450c109fbbd333001165bbd986061f7c4513John McCall = (VisibilityAttr::VisibilityType) rawType; 518cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt SourceLocation loc = Stack->back().second; 519aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); 521aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 522aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 523aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman/// FreeVisContext - Deallocate and null out VisContext. 524aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::FreeVisContext() { 525aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman delete static_cast<VisStack*>(VisContext); 5266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VisContext = nullptr; 527aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 528aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 52990f1450c109fbbd333001165bbd986061f7c4513John McCallstatic void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 530ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall // Put visibility on stack. 531ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall if (!S.VisContext) 532ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall S.VisContext = new VisStack; 533ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall 534ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall VisStack *Stack = static_cast<VisStack*>(S.VisContext); 535ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall Stack->push_back(std::make_pair(type, loc)); 536ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall} 537ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall 5383fc809de96f9b0a4fcf7bc936399194d0b7198c8Rafael Espindolavoid Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, 539aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman SourceLocation PragmaLoc) { 5403fc809de96f9b0a4fcf7bc936399194d0b7198c8Rafael Espindola if (VisType) { 541aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman // Compute visibility to use. 542d068607c136298bec0891d750389a55bac9f5c98Aaron Ballman VisibilityAttr::VisibilityType T; 543d068607c136298bec0891d750389a55bac9f5c98Aaron Ballman if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) { 544d068607c136298bec0891d750389a55bac9f5c98Aaron Ballman Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType; 545aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 546aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 547d068607c136298bec0891d750389a55bac9f5c98Aaron Ballman PushPragmaVisibility(*this, T, PragmaLoc); 548aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } else { 54920039ae1d9f520d8395899d807473b638fb48688Rafael Espindola PopPragmaVisibility(false, PragmaLoc); 550aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 551aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 552aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 553321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbournevoid Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) { 554321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne switch (OOS) { 555321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_ON: 556321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne FPFeatures.fp_contract = 1; 557321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 558321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_OFF: 559321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne FPFeatures.fp_contract = 0; 560321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 561321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_DEFAULT: 5624e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie FPFeatures.fp_contract = getLangOpts().DefaultFPContract; 563321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 564321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne } 565321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne} 566321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne 56720039ae1d9f520d8395899d807473b638fb48688Rafael Espindolavoid Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, 56820039ae1d9f520d8395899d807473b638fb48688Rafael Espindola SourceLocation Loc) { 56990f1450c109fbbd333001165bbd986061f7c4513John McCall // Visibility calculations will consider the namespace's visibility. 57090f1450c109fbbd333001165bbd986061f7c4513John McCall // Here we just want to note that we're in a visibility context 57190f1450c109fbbd333001165bbd986061f7c4513John McCall // which overrides any enclosing #pragma context, but doesn't itself 57290f1450c109fbbd333001165bbd986061f7c4513John McCall // contribute visibility. 57320039ae1d9f520d8395899d807473b638fb48688Rafael Espindola PushPragmaVisibility(*this, NoVisibility, Loc); 574aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 575aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 57620039ae1d9f520d8395899d807473b638fb48688Rafael Espindolavoid Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { 57720039ae1d9f520d8395899d807473b638fb48688Rafael Espindola if (!VisContext) { 57820039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 57920039ae1d9f520d8395899d807473b638fb48688Rafael Espindola return; 58020039ae1d9f520d8395899d807473b638fb48688Rafael Espindola } 58120039ae1d9f520d8395899d807473b638fb48688Rafael Espindola 58220039ae1d9f520d8395899d807473b638fb48688Rafael Espindola // Pop visibility from stack 58320039ae1d9f520d8395899d807473b638fb48688Rafael Espindola VisStack *Stack = static_cast<VisStack*>(VisContext); 584aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 58520039ae1d9f520d8395899d807473b638fb48688Rafael Espindola const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); 58620039ae1d9f520d8395899d807473b638fb48688Rafael Espindola bool StartsWithPragma = Back->first != NoVisibility; 58720039ae1d9f520d8395899d807473b638fb48688Rafael Espindola if (StartsWithPragma && IsNamespaceEnd) { 58820039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Diag(Back->second, diag::err_pragma_push_visibility_mismatch); 58920039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Diag(EndLoc, diag::note_surrounding_namespace_ends_here); 59020039ae1d9f520d8395899d807473b638fb48688Rafael Espindola 59120039ae1d9f520d8395899d807473b638fb48688Rafael Espindola // For better error recovery, eat all pushes inside the namespace. 59220039ae1d9f520d8395899d807473b638fb48688Rafael Espindola do { 59320039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Stack->pop_back(); 59420039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Back = &Stack->back(); 59520039ae1d9f520d8395899d807473b638fb48688Rafael Espindola StartsWithPragma = Back->first != NoVisibility; 59620039ae1d9f520d8395899d807473b638fb48688Rafael Espindola } while (StartsWithPragma); 59720039ae1d9f520d8395899d807473b638fb48688Rafael Espindola } else if (!StartsWithPragma && !IsNamespaceEnd) { 59820039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 59920039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Diag(Back->second, diag::note_surrounding_namespace_starts_here); 60020039ae1d9f520d8395899d807473b638fb48688Rafael Espindola return; 601aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 60220039ae1d9f520d8395899d807473b638fb48688Rafael Espindola 60320039ae1d9f520d8395899d807473b638fb48688Rafael Espindola Stack->pop_back(); 60420039ae1d9f520d8395899d807473b638fb48688Rafael Espindola // To simplify the implementation, never keep around an empty stack. 60520039ae1d9f520d8395899d807473b638fb48688Rafael Espindola if (Stack->empty()) 60620039ae1d9f520d8395899d807473b638fb48688Rafael Espindola FreeVisContext(); 607aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 608