SemaDeclAttr.cpp revision 73798892751e378cbcdef43579c1d41685091fd0
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" 176e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h> 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) { 270eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 2716e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange()); 272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 273eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 274465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 275465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 276eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 277eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 278eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!proto->getArgType(x).getCanonicalType()->isPointerType()) { 279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 281eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!NonNullArgs.empty()) { 289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned* start = &NonNullArgs[0]; 290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned size = NonNullArgs.size(); 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek std::sort(start, start + size); 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr(start, size)); 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek else 295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr()); 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 298803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 300545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 301803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 302803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 306545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 311803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 312803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "alias", std::string("1")); 3136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 326545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 327803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 328803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Fn) { 334803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 335803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "noreturn", "function"); 3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 34273798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 34373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 34473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 34573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 34673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek std::string("0")); 34773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 34873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 34973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 35073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek VarDecl *VD = dyn_cast<VarDecl>(d); 35173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 35273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (!VD) { 35373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 35473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek "unused", "variable"); 35573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 35673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 35773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 35873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek d->addAttr(new UnusedAttr()); 35973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 36073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 361803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 364803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 365803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 374545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 375803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 380545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 385803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 386803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", std::string("1")); 3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 3986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 403803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 404803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", TypeStr); 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 411803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 413545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 414803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 415803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 4206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 422803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 424545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 425803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 426803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 4316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 433803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 435545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 436803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 437803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 444803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 446545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 447803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 448803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 4536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 455803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 457545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 458803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 459803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 4646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 466803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 468545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 469803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 479803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 481545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 482803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 4836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("1")); 4846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 487545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 488803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 489803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("3")); 4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // GCC ignores the format attribute on K&R style function 4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // prototypes, so we ignore it as well 4956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const FunctionTypeProto *proto = getFunctionProto(d); 4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!proto) { 498803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 499803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "format", "function"); 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 5056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned NumArgs = proto->getNumArgs(); 5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 509545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 510545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner (is_NSString = !memcmp(Format, "NSString", 8)); 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 535803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 536545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner "format", Attr.getParameterName()->getName()); 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 541545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 542803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 543803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 544803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 5596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty = proto->getArgType(ArgIdx); 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_NSString) { 5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 564803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 567803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 568803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 575803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 576803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 581545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 583803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 584803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (proto->isVariadic()) { 5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any variable 6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the input is just the current time + the format string 6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FirstArgExpr->getSourceRange()); 6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 609803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 6190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 621545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 6220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner std::string("0")); 6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner TypeDecl *decl = dyn_cast<TypeDecl>(d); 6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6290b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) { 6300b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "transparent_union", "union"); 6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //QualType QTy = Context.getTypeDeclType(decl); 6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //const RecordType *Ty = QTy->getAsUnionType(); 6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME 6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr()); 6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6420b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 644545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("1")); 6476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 649545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 6550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 6606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 664545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 665803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 671545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 67749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 67849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 67949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 680803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 681803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 682803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "aligned", alignmentExpr->getSourceRange()); 68349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 68449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 68549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 6880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 689065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 690fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 691fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 693fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 6950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 700fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 7010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 7020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("0")); 703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 704fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 7080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 716fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 722fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 724fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 727fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 728fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 731fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 732fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 734fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 735fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 736fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 738fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 7390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 7410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 7450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 7550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 7560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: Need proper fixed-width types 761fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 7640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 7670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 7720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7740b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 7790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 7850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 7870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 7930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 7950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 7970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 798fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 8020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 8050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 811fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 8140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 8150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 8160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 8170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 8180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 821803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 822803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 824803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 825803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 826803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 827803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_ext_vector_type: 828803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleExtVectorTypeAttr(D, Attr, S); 829803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 830803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 832803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 838803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 839803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 840803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 841803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 842803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 846eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 847eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 84873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 851803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 856803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr->getName()->getName()); 857803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 858803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 859803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 860803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 862803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 863803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 864803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 866803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 868803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 869803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 870803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 871803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 8720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 8750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 8760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 8770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 8780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 8800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 8810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 8820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 8830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 8840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 8850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 8860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 8870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 8880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 8890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 8900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 8910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 8920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 893