SemaAttr.cpp revision 4421d2b341d041df44013769f23c306308bbab83
15a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner//===--- 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" 16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Lookup.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" 215a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattnerusing namespace clang; 225a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 23574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 24ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar// Pragma 'pack' and 'options align' 25574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner//===----------------------------------------------------------------------===// 26574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 27574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnernamespace { 28ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar struct PackStackEntry { 29c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // We just use a sentinel to represent when the stack is set to mac68k 30c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // alignment. 31c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar static const unsigned kMac68kAlignmentSentinel = ~0U; 32c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 33ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar unsigned Alignment; 34ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar IdentifierInfo *Name; 35ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar }; 36ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar 37574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// PragmaPackStack - Simple class to wrap the stack used by #pragma 38574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pack. 39574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner class PragmaPackStack { 40ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar typedef std::vector<PackStackEntry> stack_ty; 41574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 42574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Alignment - The current user specified alignment. 43574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned Alignment; 44574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 45574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// Stack - Entries in the #pragma pack stack, consisting of saved 46574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignments and optional names. 47574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner stack_ty Stack; 481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump public: 50574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack() : Alignment(0) {} 51574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 52574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void setAlignment(unsigned A) { Alignment = A; } 53574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner unsigned getAlignment() { return Alignment; } 54574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 55574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// push - Push the current alignment onto the stack, optionally 56574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// using the given \arg Name for the record, if non-zero. 57574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner void push(IdentifierInfo *Name) { 58ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar PackStackEntry PSE = { Alignment, Name }; 59ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar Stack.push_back(PSE); 60574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 61574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 62574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// pop - Pop a record from the stack and restore the current 63574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// alignment to the previous value. If \arg Name is non-zero then 64574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// the first such named record is popped, otherwise the top record 65574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner /// is popped. Returns true if the pop succeeded. 66ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar bool pop(IdentifierInfo *Name, bool IsReset); 67574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner }; 68574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} // end anonymous namespace. 69574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 70ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbarbool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) { 71574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // If name is empty just pop top. 72574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (!Name) { 73ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // An empty stack is a special case... 74ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (Stack.empty()) { 75ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // If this isn't a reset, it is always an error. 76ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!IsReset) 77ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar return false; 78ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 79ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // Otherwise, it is an error only if some alignment has been set. 80ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!Alignment) 81ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar return false; 82ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 83ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // Otherwise, reset to the default alignment. 84ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Alignment = 0; 85ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar } else { 86ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Alignment = Stack.back().Alignment; 87ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar Stack.pop_back(); 88ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar } 89ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar 90574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 93574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Otherwise, find the named record. 94574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner for (unsigned i = Stack.size(); i != 0; ) { 95574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner --i; 96ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar if (Stack[i].Name == Name) { 97574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner // Found it, pop up to and including this record. 98ae2232b9957302374ee8d8626aeedcb4e4c0441eDaniel Dunbar Alignment = Stack[i].Alignment; 99574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Stack.erase(Stack.begin() + i, Stack.end()); 100574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return true; 101574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 102574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner } 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 104574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner return false; 105574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 106574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 107574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 108574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner/// FreePackedContext - Deallocate and null out PackContext. 109574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattnervoid Sema::FreePackedContext() { 110574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner delete static_cast<PragmaPackStack*>(PackContext); 111574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PackContext = 0; 112574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 113574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 1149f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbarvoid Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 1159f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar // If there is no pack context, we don't need any attributes. 1169f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar if (!PackContext) 1179f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar return; 1189f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar 1199f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar PragmaPackStack *Stack = static_cast<PragmaPackStack*>(PackContext); 1209f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar 1219f21f89c323ccf32f6b27acd2e739f6535440df0Daniel Dunbar // Otherwise, check to see if we need a max field alignment attribute. 122c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (unsigned Alignment = Stack->getAlignment()) { 123c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (Alignment == PackStackEntry::kMac68kAlignmentSentinel) 124cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context)); 125c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar else 126cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(), 127cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Context, 128cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Alignment * 8)); 129c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 130574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner} 131574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner 132ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbarvoid Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 133ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar SourceLocation PragmaLoc, 134ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar SourceLocation KindLoc) { 135ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar if (PackContext == 0) 136ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar PackContext = new PragmaPackStack(); 137ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 138ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 139ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 140ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // Reset just pops the top of the stack, or resets the current alignment to 141ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar // default. 142f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (Kind == Sema::POAK_Reset) { 143ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!Context->pop(0, /*IsReset=*/true)) { 144ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 145ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar << "stack empty"; 146ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar } 147ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar return; 148ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar } 149ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 150ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar switch (Kind) { 151638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // For all targets we support native and natural are the same. 152638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // 153638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar // FIXME: This is not true on Darwin/PPC. 154638e7cf3a09436dce7f3150ff8e4f27d190bd2edDaniel Dunbar case POAK_Native: 155450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar case POAK_Power: 156d6b305dcba95fc4928a2baa6bbeb15d22db9d061Daniel Dunbar case POAK_Natural: 157450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar Context->push(0); 158450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar Context->setAlignment(0); 159450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar break; 160450f79340808e54cd4b39738f943217f6fc0c2beDaniel Dunbar 1616f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar // Note that '#pragma options align=packed' is not equivalent to attribute 1626f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar // packed, it has a different precedence relative to attribute aligned. 1636f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar case POAK_Packed: 1646f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar Context->push(0); 1656f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar Context->setAlignment(1); 1666f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar break; 1676f739145b94ede1ca98b5a5e0e179c817c405d7bDaniel Dunbar 168613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar case POAK_Mac68k: 169613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar // Check if the target supports this. 170613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar if (!PP.getTargetInfo().hasAlignMac68kSupport()) { 171613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 172613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar return; 173613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar } 174c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Context->push(0); 175c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel); 176613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar break; 177613fd67e575ff1c038535b18dafebca070f3ed91Daniel Dunbar 178ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar default: 179ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option) 180ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar << KindLoc; 181ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar break; 182ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar } 183ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar} 184ea75a8286fb87ce7549e08d9dcb597f91479f54dDaniel Dunbar 1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, 1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ExprTy *alignment, SourceLocation PragmaLoc, 1875a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner SourceLocation LParenLoc, SourceLocation RParenLoc) { 1885a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Expr *Alignment = static_cast<Expr *>(alignment); 1895a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 1905a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If specified then alignment must be a "small" power of two. 1915a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner unsigned AlignmentVal = 0; 1925a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) { 1935a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner llvm::APSInt Val; 1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19579cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // pack(0) is like pack(), which just works out since that is what 19679cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar // we use 0 for in PackAttr. 197ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Alignment->isTypeDependent() || 198ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor Alignment->isValueDependent() || 199ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Alignment->isIntegerConstantExpr(Val, Context) || 20079cd11620c6f05dbf7bb706744eba354574e8b54Daniel Dunbar !(Val == 0 || Val.isPowerOf2()) || 2015a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Val.getZExtValue() > 16) { 2025a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 2035a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner return; // Ignore 2045a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2055a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 2065a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = (unsigned) Val.getZExtValue(); 2075a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 209574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner if (PackContext == 0) 210574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PackContext = new PragmaPackStack(); 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 212574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext); 2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2145a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner switch (Kind) { 215f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Default: // pack([n]) 216574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 2175a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2185a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 219f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Show: // pack(show) 2205a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Show the current alignment, making sure to show the right value 2215a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // for the default. 222574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner AlignmentVal = Context->getAlignment(); 2235a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: This should come from the target. 2245a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (AlignmentVal == 0) 2255a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner AlignmentVal = 8; 226c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (AlignmentVal == PackStackEntry::kMac68kAlignmentSentinel) 227c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; 228c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar else 229c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 2305a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2315a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 232f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Push: // pack(push [, id] [, [n]) 233574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->push(Name); 2345a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Set the new alignment if specified. 2355a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Context->setAlignment(AlignmentVal); 2375a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2385a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 239f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall case Sema::PPK_Pop: // pack(pop [, id] [, n]) 2405a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 2415a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // "#pragma pack(pop, identifier, n) is undefined" 2425a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment && Name) 2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2455a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Do the pop. 246ddc6ff6b9aff656504c1e84ee7dc9f617a20f866Daniel Dunbar if (!Context->pop(Name, /*IsReset=*/false)) { 2475a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // If a name was specified then failure indicates the name 2485a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // wasn't found. Otherwise failure indicates the stack was 2495a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // empty. 2505a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed) 2515a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner << (Name ? "no record matching name" : "stack empty"); 2525a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 2535a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // FIXME: Warn about popping named records as MSVC does. 2545a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } else { 2555a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner // Pop succeeded, set the new alignment if specified. 2565a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner if (Alignment) 257574aa40703ffb2fddad5b076cec1c2fc27f0b2d3Chris Lattner Context->setAlignment(AlignmentVal); 2585a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2595a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner break; 2605a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 2615a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner default: 2625a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner assert(0 && "Invalid #pragma pack kind."); 2635a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner } 2645a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner} 2655a0c35150102f95ab270f741cdab5907c9bd9017Chris Lattner 266b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidisvoid Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 267b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis SourceLocation PragmaLoc) { 2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 269b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis IdentifierInfo *Name = IdTok.getIdentifierInfo(); 270b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 271b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis LookupParsedName(Lookup, curScope, NULL, true); 2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 273b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis if (Lookup.empty()) { 274b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 275b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis << Name << SourceRange(IdTok.getLocation()); 276b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis return; 277b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis } 2782127eccbe15fd3b1b29aa53ccedd2e0f55ad27f9Anders Carlsson 279b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 2802a5c45b1ae4406459fbb39cb477951987c59cb0fArgyrios Kyrtzidis if (!VD) { 2812a5c45b1ae4406459fbb39cb477951987c59cb0fArgyrios Kyrtzidis Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 282b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis << Name << SourceRange(IdTok.getLocation()); 283b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis return; 2844726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek } 285b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis 286b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis // Warn if this was used before being marked unused. 287b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis if (VD->isUsed()) 288b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 289b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis 290b918d0f5d8f147e1e26c34e6cf42a79af2d2ec41Argyrios Kyrtzidis VD->addAttr(::new (Context) UnusedAttr(IdTok.getLocation(), Context)); 2914726d03ab3abce41911c31d1354a18f1258cae4dTed Kremenek} 292aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 29390f1450c109fbbd333001165bbd986061f7c4513John McCalltypedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 29490f1450c109fbbd333001165bbd986061f7c4513John McCallenum { NoVisibility = (unsigned) -1 }; 295aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 296aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::AddPushedVisibilityAttribute(Decl *D) { 297aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (!VisContext) 298aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 299aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 3004421d2b341d041df44013769f23c306308bbab83Douglas Gregor if (isa<NamedDecl>(D) && cast<NamedDecl>(D)->getExplicitVisibility()) 301aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 302aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 303aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman VisStack *Stack = static_cast<VisStack*>(VisContext); 30490f1450c109fbbd333001165bbd986061f7c4513John McCall unsigned rawType = Stack->back().first; 30590f1450c109fbbd333001165bbd986061f7c4513John McCall if (rawType == NoVisibility) return; 30690f1450c109fbbd333001165bbd986061f7c4513John McCall 30790f1450c109fbbd333001165bbd986061f7c4513John McCall VisibilityAttr::VisibilityType type 30890f1450c109fbbd333001165bbd986061f7c4513John McCall = (VisibilityAttr::VisibilityType) rawType; 309cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt SourceLocation loc = Stack->back().second; 310aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 311cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) VisibilityAttr(loc, Context, type)); 312aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 313aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 314aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman/// FreeVisContext - Deallocate and null out VisContext. 315aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::FreeVisContext() { 316aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman delete static_cast<VisStack*>(VisContext); 317aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman VisContext = 0; 318aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 319aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 32090f1450c109fbbd333001165bbd986061f7c4513John McCallstatic void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 321ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall // Put visibility on stack. 322ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall if (!S.VisContext) 323ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall S.VisContext = new VisStack; 324ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall 325ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall VisStack *Stack = static_cast<VisStack*>(S.VisContext); 326ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall Stack->push_back(std::make_pair(type, loc)); 327ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall} 328ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall 329aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType, 330aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman SourceLocation PragmaLoc) { 331aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (IsPush) { 332aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman // Compute visibility to use. 333cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 334aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (VisType->isStr("default")) 335cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 336aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman else if (VisType->isStr("hidden")) 337cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 338aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman else if (VisType->isStr("internal")) 339cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 340aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman else if (VisType->isStr("protected")) 341cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 342aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman else { 343aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << 344aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman VisType->getName(); 345aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman return; 346aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 347ea318642072d3d94b5c3cff0fa6f4b33d2db0768John McCall PushPragmaVisibility(*this, type, PragmaLoc); 348aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } else { 349aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman PopPragmaVisibility(); 350aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 351aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 352aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 353321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbournevoid Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) { 354321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne switch (OOS) { 355321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_ON: 356321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne FPFeatures.fp_contract = 1; 357321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 358321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_OFF: 359321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne FPFeatures.fp_contract = 0; 360321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 361321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne case tok::OOS_DEFAULT: 362321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne FPFeatures.fp_contract = getLangOptions().DefaultFPContract; 363321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne break; 364321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne } 365321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne} 366321b8179afaf803dcc56b2a19f7b0891a03c92c8Peter Collingbourne 36790f1450c109fbbd333001165bbd986061f7c4513John McCallvoid Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr) { 36890f1450c109fbbd333001165bbd986061f7c4513John McCall // Visibility calculations will consider the namespace's visibility. 36990f1450c109fbbd333001165bbd986061f7c4513John McCall // Here we just want to note that we're in a visibility context 37090f1450c109fbbd333001165bbd986061f7c4513John McCall // which overrides any enclosing #pragma context, but doesn't itself 37190f1450c109fbbd333001165bbd986061f7c4513John McCall // contribute visibility. 37290f1450c109fbbd333001165bbd986061f7c4513John McCall PushPragmaVisibility(*this, NoVisibility, SourceLocation()); 373aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 374aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 375aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedmanvoid Sema::PopPragmaVisibility() { 376aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman // Pop visibility from stack, if there is one on the stack. 377aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (VisContext) { 378aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman VisStack *Stack = static_cast<VisStack*>(VisContext); 379aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman 380aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman Stack->pop_back(); 381aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman // To simplify the implementation, never keep around an empty stack. 382aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman if (Stack->empty()) 383aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman FreeVisContext(); 384aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman } 385aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman // FIXME: Add diag for pop without push. 386aa8b0d19244a6e7e8e5798fcc6aef003c274d3e0Eli Friedman} 387