SemaDeclAttr.cpp revision 465172f304248a9aab6f2c398a836ce4e25efbbf
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h" 156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 16fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 17465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek#include <sstream> 186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 21e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 22e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic const FunctionTypeProto *getFunctionProto(Decl *d) { 256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = Ty->getAsPointerType()->getPointeeType(); 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (const FunctionType *FnTy = Ty->getAsFunctionType()) 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType()); 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!T->isPointerType()) 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner T = T->getAsPointerType()->getPointeeType().getCanonicalType(); 496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr()); 506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 61e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 62e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 63e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 64e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 65803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 66803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 67545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 68545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 69803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 70545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 75545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 76803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 77803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 80545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 82803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 83803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 84803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "ext_vector_type", sizeExpr->getSourceRange()); 856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Type *canonType = curType.getCanonicalType().getTypePtr(); 906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { 91803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 92803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner curType.getCanonicalType().getAsString()); 936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 100803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 101803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 105803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 107803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 110065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 111065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 112065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 113065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 114065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 115065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 116065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 117065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 118065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 119803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 120065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 121065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 122065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 123065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 124065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 125065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 126803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, 127803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("vector_size"), 128803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 129065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 130065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 131065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 132065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 133545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 135803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 136065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 138545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 142803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "vector_size", sizeExpr->getSourceRange()); 143065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 147065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner Type *canonType = CurType.getCanonicalType().getTypePtr(); 1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (canonType->isPointerType() || canonType->isArrayType() || 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()) { 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { 166803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 167803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType.getCanonicalType().getAsString()); 168065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 176803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size, 177803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 181803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 182803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 188803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 1946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 196803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 198545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 199803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 200803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 20549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner TD->addAttr(new PackedAttr()); 2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 210803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), 212803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner diag::warn_attribute_ignored_for_field_of_type, 213803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName(), FD->getType().getAsString()); 2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 21549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner FD->addAttr(new PackedAttr()); 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 217803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored, 218803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName()); 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 22296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 22396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 22496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 22596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek std::string("0")); 22696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 22796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 22896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 23196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek ID->addAttr(new IBOutletAttr()); 23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 23496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 237eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 238eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 239eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 240eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 241eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek const FunctionTypeProto *proto = getFunctionProto(d); 242eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 243eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!proto) { 244eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 245eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", "function"); 246eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 249eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned NumArgs = proto->getNumArgs(); 250eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 251eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 252eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 253eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 254eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 255eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 256eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 257eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 258eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 259eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek Expr *Ex = static_cast<Expr *>(Attr.getArg(0)); 260eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 261eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 262eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 263eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 264eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 265eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 266eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 267eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 268eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 269eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 270465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek std::ostringstream os; 271465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek os << I.getArgNum(); 272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 273465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek "nonnull", os.str(), Ex->getSourceRange()); 274eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 275eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 276465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 277465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 278eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!proto->getArgType(x).getCanonicalType()->isPointerType()) { 281eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!NonNullArgs.empty()) { 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned* start = &NonNullArgs[0]; 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned size = NonNullArgs.size(); 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek std::sort(start, start + size); 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr(start, size)); 295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek else 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr()); 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 300803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 302545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 303803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 304803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 308545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "alias", std::string("1")); 3156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 328545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 329803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 3356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Fn) { 336803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "noreturn", "function"); 3386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 3426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 344803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 346545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 347803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 3536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 355803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 357545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 358803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 359803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 368803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 369803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", std::string("1")); 3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 3766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 386803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 387803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", TypeStr); 3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 394803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 396545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 397803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 405803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 407545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 408803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 409803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 418545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 419803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 4256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 427803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 429545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 430803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 431803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 4366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 438803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 440545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 441803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 442803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 4476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 449803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 451545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 453803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 462803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 464545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 465803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 4666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("1")); 4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 470545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 471803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 472803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("3")); 4736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // GCC ignores the format attribute on K&R style function 4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // prototypes, so we ignore it as well 4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const FunctionTypeProto *proto = getFunctionProto(d); 4796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!proto) { 481803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 482803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "format", "function"); 4836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned NumArgs = proto->getNumArgs(); 4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 492545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 5056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 508803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 509803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 510803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner (is_NSString = !memcmp(Format, "NSString", 8)); 5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 518803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 519545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner "format", Attr.getParameterName()->getName()); 5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 524545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 533803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty = proto->getArgType(ArgIdx); 5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_NSString) { 5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 547803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 551803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 558803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 559803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 564545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 565803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 566803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 567803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 5686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (proto->isVariadic()) { 5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 5766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 577803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any variable 5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the input is just the current time + the format string 5846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 586803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FirstArgExpr->getSourceRange()); 5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 6020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 604545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 6050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner std::string("0")); 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner TypeDecl *decl = dyn_cast<TypeDecl>(d); 6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) { 6130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "transparent_union", "union"); 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //QualType QTy = Context.getTypeDeclType(decl); 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //const RecordType *Ty = QTy->getAsUnionType(); 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME 6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr()); 6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6250b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 627545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6290b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("1")); 6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 632545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 6380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 6426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 645803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 647545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 648803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 649803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 654545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 66049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 66149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 66249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 663803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 664803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 665803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "aligned", alignmentExpr->getSourceRange()); 66649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 66749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 66849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 6710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 672065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 675fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 6780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 683fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 6840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("0")); 686fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 688fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 6910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 701fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 7220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 7240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 7280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 7380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 7390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: Need proper fixed-width types 744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 7470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 7500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 7550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 7620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 7680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 7700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 7760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 7780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 7850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 7880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 7970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 7980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 7990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 8000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 8010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 802803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 803803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 805803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 809803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 810803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_ext_vector_type: 811803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleExtVectorTypeAttr(D, Attr, S); 812803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 814803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 815803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 816803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 821803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 822803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 825803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 827803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 828803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 829eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 830eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 832803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 838803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr->getName()->getName()); 839803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 840803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 841803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 848803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 8540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 8550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 8560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 8570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 8580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 8590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 8600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 8620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 8630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 8640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 8650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 8660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 8670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 8680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 8690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 8700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 8710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 8720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 875