SemaDeclAttr.cpp revision acc5f3e42334525bf28c86471551f83dfce222d5
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" 16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 18e4858a65a93fb36c099d8dd2ea0a98e33e77687eDaniel Dunbar#include "clang/Basic/Diagnostic.h" 19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 216e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h> 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic const FunctionTypeProto *getFunctionProto(Decl *d) { 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = Ty->getAsPointerType()->getPointeeType(); 416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (const FunctionType *FnTy = Ty->getAsFunctionType()) 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType()); 446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 49b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 50b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 53b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 64e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 65e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 66e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 67e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 72803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 73803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 74545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 75545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 76803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 77545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 82545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 83803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 84803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 87545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 89803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 90803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 91803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "ext_vector_type", sizeExpr->getSourceRange()); 926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 96b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 97803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner curType.getAsString()); 996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 106803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 107803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 111803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 113803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 116065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 117065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 118065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 119065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 120065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 121065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 122065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 123065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 124065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 125803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 126065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 127065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 128065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 129065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 130065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 131065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 132803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, 133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("vector_size"), 134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 135065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 136065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 137065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 138065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 142065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 144545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 146803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 148803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "vector_size", sizeExpr->getSourceRange()); 149065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 153b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 154b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 169b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 171b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType.getAsString()); 172065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 180803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size, 181803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 185803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 186803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 192803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 195065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 1986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 200803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 202545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 203803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 20949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner TD->addAttr(new PackedAttr()); 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 214803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), 216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner diag::warn_attribute_ignored_for_field_of_type, 217803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName(), FD->getType().getAsString()); 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 21949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner FD->addAttr(new PackedAttr()); 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 221803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored, 222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName()); 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 22696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 22796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 22896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek std::string("0")); 23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 23196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 23496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek ID->addAttr(new IBOutletAttr()); 23796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 23896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 23996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 24096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 241eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 242eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 243eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 244eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 245eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek const FunctionTypeProto *proto = getFunctionProto(d); 246eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!proto) { 247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", "function"); 249eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 250eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 251eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 252eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned NumArgs = proto->getNumArgs(); 253eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 254eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 255eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 256eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 257eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 258eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 259eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 260eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 261eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 262eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek Expr *Ex = static_cast<Expr *>(Attr.getArg(0)); 263eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 264eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 265eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 266eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 267eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 268eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 269eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 270eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 271eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 273eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 2746e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange()); 275eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 276eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 277465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 278465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 279eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 281b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!proto->getArgType(x)->isPointerType()) { 282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 284eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 285eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 288eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 290eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!NonNullArgs.empty()) { 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned* start = &NonNullArgs[0]; 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned size = NonNullArgs.size(); 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek std::sort(start, start + size); 295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr(start, size)); 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek else 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek d->addAttr(new NonNullAttr()); 299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 301803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 303545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 304803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 305803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 309545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 315803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "alias", std::string("1")); 3166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 327803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 329545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 331803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Fn) { 337803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 338803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "noreturn", "function"); 3396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 3436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 34573798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 34673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 34773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 34873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 34973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek std::string("0")); 35073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 35173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 35273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 353356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek if (!isa<VarDecl>(d) && !getFunctionProto(d)) { 35473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 355356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek "unused", "variable and function"); 35673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 35773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 35873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 35973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek d->addAttr(new UnusedAttr()); 36073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 36173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 3623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 3643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 3653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 3663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 3673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 3683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 3693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 3703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 3713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 3723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 3733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 3743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 3753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "1", E->getSourceRange()); 3763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 3773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 3783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 3793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 3803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 3813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 3823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!Fn) { 3833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 3843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "function"); 3853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 3863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 3873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 3883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new ConstructorAttr(priority)); 3893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 3903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 3913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 3933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 3943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 3953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 3963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 3973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 3983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 3993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 4033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 4043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "1", E->getSourceRange()); 4053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 4113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!Fn) { 4123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 4133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "function"); 4143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new DestructorAttr(priority)); 4183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 422545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 423803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 424803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 431803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 433545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 434803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 435803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 4366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 439545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 4406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 4416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 444803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 445803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", std::string("1")); 4466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 4506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 4516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 4526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 4556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 4576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 4596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 4606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 4616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 462803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 463803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", TypeStr); 4646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 4686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 472545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 473803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 474803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 4796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 481803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 483545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 484803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 485803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 492803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 494545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 495803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 496803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 503803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 505545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 506803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 507803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 514803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 516545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 517803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 518803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 525803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 527545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 528803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 529803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 538803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 540545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 541803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("1")); 5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 546545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 547803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 548803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("3")); 5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // GCC ignores the format attribute on K&R style function 5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // prototypes, so we ignore it as well 5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const FunctionTypeProto *proto = getFunctionProto(d); 5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!proto) { 557803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 558803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "format", "function"); 5596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 5646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned NumArgs = proto->getNumArgs(); 5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 568545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 569545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 5766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 584803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 585803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 586803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner (is_NSString = !memcmp(Format, "NSString", 8)); 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 595545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner "format", Attr.getParameterName()->getName()); 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 600545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 601803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 602803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 609803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty = proto->getArgType(ArgIdx); 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_NSString) { 6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 623803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 626803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString, 627803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 634803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string, 635803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner IdxExpr->getSourceRange()); 6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 640545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 641803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 642803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 643803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 6446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 6456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 6496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (proto->isVariadic()) { 6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 653803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any variable 6596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the input is just the current time + the format string 6606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FirstArgExpr->getSourceRange()); 6646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 668803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 6780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 680545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 6810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 6826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner std::string("0")); 6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner TypeDecl *decl = dyn_cast<TypeDecl>(d); 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner if (!decl || !S.Context.getTypeDeclType(decl)->isUnionType()) { 6890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "transparent_union", "union"); 6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //QualType QTy = Context.getTypeDeclType(decl); 6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner //const RecordType *Ty = QTy->getAsUnionType(); 6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// FIXME 6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// Ty->addAttr(new TransparentUnionAttr()); 6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 703545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 7040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 7050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("1")); 7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 708545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 7140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 7196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 723545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 724803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 725803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 730545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 73649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 73749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 73849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 739803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 740803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 741803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "aligned", alignmentExpr->getSourceRange()); 74249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 74349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 74449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 7456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 7470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 748065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 7540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 7600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 7610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("0")); 762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 765fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 7670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 771fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 773fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 777fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 785fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 791fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 797fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 7980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 8000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 801fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 802fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 8040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 805fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 809fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 810fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 811fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 812fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 8140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 8150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 816fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 817fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 818fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 819fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: Need proper fixed-width types 820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 821fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 822fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 8230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 824fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 8260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 828fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 829fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 830fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 8310b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 832fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 8330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 834fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 835fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 836fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 837fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 8380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 839fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 8400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 841fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 842fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 843fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 8440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 845fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 8460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 847fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 8480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 849fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 850fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 851fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 8520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 853fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 8540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 855fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 8560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 857fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 858fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 859fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 860fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 8610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 863fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 8640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 865fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 866fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 867fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 868fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 869fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 870fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 871fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 872fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 8730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 8740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 8750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 8760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 8770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 878803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 880803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 881803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 882803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 8833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 884803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 885803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 886803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 887803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 8883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 8893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 8903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 891803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 8923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 893803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 8943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 8953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 8963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 8973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 898803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 899803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 9003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 901eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 9023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 9033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 9043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 9053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 90673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 9073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 9083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 9093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 910803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 911803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 912803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 913803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 914803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 915803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 916803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 917803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr->getName()->getName()); 918803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 919803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 920803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 921803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 922803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 923803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 924803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 925803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 926803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 927803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 928803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 929803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 930803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 931803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 932803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 9330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 9340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 9350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 9360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 9370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 9380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 9390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 940803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 9410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 9420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 9430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 9440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 9450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 9460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 9470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 9480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 9490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 9500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 9510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 9520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 9530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 954