SemaDeclAttr.cpp revision 63e5d7c85299134f088033614afd9eb213c50b48
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" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 21797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 28a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d, 29a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 33a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 35a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 39bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 416217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 42755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 44d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 45183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 51d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) { 54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return getFunctionType(d, false) != NULL; 55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) { 61a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return isFunction(d)|| isa<ObjCMethodDecl>(d); 62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 633568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 66620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 67a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) { 68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 70620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 75d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 82620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 8372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 84620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 85d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 91d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 92d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 93a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 9489951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 9572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 9889951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1003568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 101a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 10289951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 104d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 105d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 110a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 116a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 117d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 11872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 120d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 121d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->IsVariadic(); 122d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1253568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1263568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 128183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 129b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 131bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 132183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>(); 1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 143085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 147085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 159e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 160e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 161e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 162e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 170545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 181f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 182f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 183f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 184f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 198ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 199a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 214a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson TD->addAttr(::new (S.Context) PackedAttr); 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 219803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 22108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 223a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson FD->addAttr(::new (S.Context) PackedAttr); 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 22996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 23096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 23663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 23763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 23863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek d->addAttr(::new (S.Context) IBActionAttr()); 23963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 24063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 24163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 24363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 24763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 253efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 254efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek d->addAttr(::new (S.Context) IBOutletAttr()); 25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 257efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 25863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 26096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 26196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 262eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 263bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 265d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 266fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 268eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 269eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 270bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 271d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 272eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 273eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 274eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 275bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 276eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 277eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 279bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 280eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 281f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 282eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 283eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 284fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 285fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 286eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 287eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 289eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 292fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 29330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 296bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 297465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 301dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 303fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 304fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3057fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 307bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 310bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 311bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 312bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 31446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 31546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 316dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 317d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 31846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3207fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3217fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3227fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3237fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3267fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3277fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3287fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3295961611172f1c210fbbaa55b3c692e13b1fc7be4Ted Kremenek d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size)); 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 332803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 334545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 339545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 3466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 348bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3513d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString())); 3526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 355af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 356af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 357af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 3583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 359af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 360af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 3615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 362c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 3635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 3655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 3665bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 36840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlwaysInlineAttr()); 369af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 370af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 37176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 37276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn // check the attribute arguments. 37376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 37476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 37576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 37676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3782cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 3802cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 3812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek d->addAttr(::new (S.Context) MallocAttr()); 3822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 3832cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 384fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 385fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 3862cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 38776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 38876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 389b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 3905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek Sema &S) { 3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 392545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 3933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 394b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 396d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 39719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 39819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 3993ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 4003ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), 402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : diag::warn_attribute_wrong_decl_type) 4045dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 40519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump return false; 40619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 409b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 410b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 411b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 412b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 41304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // Don't apply as a decl attribute to ValueDecl. 41404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // FIXME: probably ought to diagnose this. 41504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall if (isa<ValueDecl>(d)) 41604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall return; 41704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall 418bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 41940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoReturnAttr()); 420b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 421b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 422b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 423b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 424bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 42540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 4266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 43104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall << Attr.getName() << 8 /*function, method, or parameter*/; 432bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 433bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 434bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 435bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 436bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 43773798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 43873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 43973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 44173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 44273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 443bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 444d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 445fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4465dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 44773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 44873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 449bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 45040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnusedAttr()); 45173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 45273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 453b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 454b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 455b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 456b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 459bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 460b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 461186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 462b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 464b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 465b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 468b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 470bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 47140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UsedAttr()); 472b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 473b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 478fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 4813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 487fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 4883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 4893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 494c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 495fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 4973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 50040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstructorAttr(priority)); 5013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 506fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 507fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 5103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 516fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 5183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 522bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5236782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 524fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5255dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 52940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DestructorAttr(priority)); 5303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 532803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 534545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 5353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 538bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 53940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DeprecatedAttr()); 5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 542bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 543bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 544bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 545bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 546bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 547bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 54940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnavailableAttr()); 550bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 551bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 552803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 554545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 5553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 559545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 562bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 564fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 568bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 569c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 572c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 574c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 576c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 578c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 58108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 58540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) VisibilityAttr(type)); 5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5880db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 5890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 5900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 5910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 5930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 5960db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 5970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 5980db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 5990db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 600bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 60140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr()); 6020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 6030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 605fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 606fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 607fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 608fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 610fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 611fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 6126217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 613fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 614fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 615fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 616fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 61740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 618fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 619fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 621f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 622f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 623f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 624f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 625f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 626f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 627f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 628f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 629f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 630f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 631f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 63240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr()); 633f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 634f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 636bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 637fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6399eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6449eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 646bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 64892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 651fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 6539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 655bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 65640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) BlocksAttr(type)); 6579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 6589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 661770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 662fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 663fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 664770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 667770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 668770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 669770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 670770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 671770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 672fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 674770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 675770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 676770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 679fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 680fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 684770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 685770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 690fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 694770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 695bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 699fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 700fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 701770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 702770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 703770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 706183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 707897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 708bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 709897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 710897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 711897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 712897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 714897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7153bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 719770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 7203bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 7222f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7232f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 724bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 725bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 7262f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 7272f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 7282f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 729daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 731183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 7322f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7333bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 7343bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 7352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7362f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 737ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 7382f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 739ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 7402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 742770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 743fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 744ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 745770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 746770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 74740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 748770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 749770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 750026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 751026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 752026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 753026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 754026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 755026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 756026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 757d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes if (!isFunctionOrMethod(D)) { 758026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7595dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 760026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 761026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 762bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 763f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes if (getFunctionType(D)->getResultType()->isVoidType()) { 764f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes S.Diag(Attr.getLoc(), diag::warn_attribute_void_function) 765f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes << Attr.getName(); 766f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 767f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 768f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes 769d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes D->addAttr(::new (S.Context) WarnUnusedResultAttr()); 770026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 771026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 772026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 774545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 779f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 780f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian bool isStatic = false; 781f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 782f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = VD->getStorageClass() == VarDecl::Static; 783f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 784f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = FD->getStorageClass() == FunctionDecl::Static; 785f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 786f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (isStatic) { 787f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 788f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 789f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 790f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 791f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 7926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 7936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 7946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7955dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 7966e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 7976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 79940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakAttr()); 8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 8046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 8056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 807bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 8086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 8106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 8116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 8126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 8136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 8146fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis isDef = FD->getBody(); 815d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 816d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 8171c90f4dc686ab872013544664c797604a309c563Mike Stump return; 8185f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 8196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8205dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 8256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 8276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 8286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 8296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 83240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr()); 8336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 8346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 8366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 8376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 8386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 8396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 8406f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 8416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 8426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 8436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 8446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 8456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Expr *E = static_cast<Expr *>(Attr.getArg(i)); 8466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 8476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 8486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 8496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 8506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 8516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 8526f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 8536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 85440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 8556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 8566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 8576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 858026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 85917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 86017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 86117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 86217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 86317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 86417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 86517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 86617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 867797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 868797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 86917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 870797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 87117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 87217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 8731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 874797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 875bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 876a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 877a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 878a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 879797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 880797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 8811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 882a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 883a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 884a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 885a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 886a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 887a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 8883d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString())); 88917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 89017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 8916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 892803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 894545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 898bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 89940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoThrowAttr()); 9006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 902232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 903232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 904232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 9053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 906232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 907232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 90940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstAttr()); 910232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 911232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 912232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 913232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 914232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 9153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 916232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 917232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 91940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) PureAttr()); 920232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 921232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 922f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 923bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 924f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 925f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 926f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 928f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 929f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 930f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 931f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 932bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 933f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 934bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 935f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 936f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 937f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 938f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 939bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 940f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 941f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 942f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 943f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall Sema::LookupOrdinaryName); 944f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 94589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 946f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 947f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 948f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 949bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 950f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 951f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 95289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 953f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 954f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 955f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 956f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 957f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 95889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 959f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 960f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 961f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 96389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 96489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 96589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 96689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 967d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 968bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 96989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 97089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 97189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 97289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 97440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CleanupAttr(FD)); 975f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 976f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 977bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 978bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 9815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 9825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 9835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 9845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 9855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 9875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 9885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 990bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start with 1. 9915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned NumArgs = getFunctionOrMethodNumArgs(d); 9925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 9935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 9945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 9955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 9965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 9975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 9995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 10005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 10035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 10045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 10055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 10065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1007bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 10115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1012bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 10145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 10155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 10165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 10176217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 10185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 10195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1020bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 10215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 10225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 10245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 10255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 10265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 10275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 10286217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 10295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 10305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1031bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 10325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 10335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1034bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1035bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 103640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 10375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 10385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 10392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 10402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 10412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 10422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 10432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 10442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 10452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 10462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 10472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 10482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 10492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 10502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 10512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 10522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 10532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 10542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 10552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 10562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 10572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 10582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 10592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 10602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 10612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 10622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 10632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 10642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 10652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 10662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 10672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1068bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1069bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1070803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1072545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1073fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 10743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1078545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 10793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 10806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1083620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1084fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10855dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 10906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 10916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 109201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 10952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 10962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 10972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 10982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 10992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 11002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1101fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 110201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 11036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1107545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1108803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1109803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1110fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 11126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11154fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // FIXME: We should handle the implicit 'this' parameter in a more generic 11164fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // way that can be used for other arguments. 11174fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson bool HasImplicitThisParam = false; 11184fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 11194fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (MD->isInstance()) { 11204fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson HasImplicitThisParam = true; 11214fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson NumArgs++; 11224fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 11234fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1126fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 11286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 11326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11344a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 11354a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 11364a2614e94672c47395abcde60518776fbebec589Sebastian Redl S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 11374a2614e94672c47395abcde60518776fbebec589Sebastian Redl << "a string type" << IdxExpr->getSourceRange(); 11384a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 11394a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 11404a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 11414a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 11443568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1147085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1148fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1149fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1151085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 11522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1153390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1154390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1156390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1157fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1158fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 11596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 11616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 11626217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1163390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1164fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1165fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 11666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1170545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1172803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1173fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 11756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 11796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 11803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 11826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1183803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 11893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 11902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 11916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1192fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1193fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 11946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1198fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11993c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12033d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(), 12042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 12080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1210545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 12113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 12160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1217bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 12180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 12190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 12200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 12210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 12220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 12230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1224fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12255dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 12310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 12320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 12340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 123517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 123617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 12370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 12380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 12390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1241bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 12420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 12430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 12440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 12460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_floating); 12470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1249bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 12500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 12510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 12520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 12530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 12540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 12550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 12560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 12570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1258bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 12590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1260bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 12610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 12620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 12630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 12650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 12660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1267bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1268bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1269bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 12706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 127140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr()); 12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12740b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1276545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 12773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1280797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1281797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1282bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 12846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 12856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1286797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 12876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12893d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); 12906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1292803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1294545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 12953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1298bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1299bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1300bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1301bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1304545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 13056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 13067549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 13076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 130840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Align)); 13096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1311bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 131249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 131349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1315fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1316fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 131749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 131849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1319396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1320bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1321396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar << alignmentExpr->getSourceRange(); 1322396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1323396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1324396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 132540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 13266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1327fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1328bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1329bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1330fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 13340b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1335fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1336fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1337fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1338fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1339fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 13403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1341fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1342fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1343fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1344fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1345fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 13460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1347fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1348fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1349210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 135001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 1351fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1353210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 1354210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 1355fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1356fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1357fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 135873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1359210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 1360fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 136173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 136273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 136373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 136473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 136573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 136673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 136773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 136873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 136973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 137073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 137173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 137273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 137373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 137473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 137573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 137673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1377fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1378fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1379fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1380fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1381210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 13820b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1383210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 13840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1385fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1386fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1387210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 13880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1389fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1390fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1391fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1392fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1393fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1394fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1395fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1396fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1397fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1398fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1399fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1400fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1401fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 140273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1403183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 140473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 140573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 140673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isIntegralType()) 140773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 140873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 140973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 141073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 141173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 141273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 141373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 141473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 141573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1416390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1417390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1418390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1419390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1420f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1421f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1422fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1423fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1424fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 14253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1426fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1427fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 14283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1429fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1430fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 143173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 143273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 143373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 143473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1435fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 14360b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1437fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1439fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1440fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 144173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 144273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 144373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 144473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1445fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 14460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1447fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1449fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1450fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1451fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 14520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1453fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 14540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1455fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1457fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1458fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1459fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 14600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1461fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 1462aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1463aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 1464aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1465aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 1466fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1467aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1468aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 1469aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1470aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 1471fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 147273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 147373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 147473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1475f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1476f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1477f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1478f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1479f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1480f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 1481f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 1482f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 1483f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 148473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 148773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 148873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1489fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1492ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1493ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 1494a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1495ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 1496fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 14980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 14991feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1500d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1501d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1502d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1503d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1504d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1505e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 15065bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1507d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1509d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1510d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1511bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15121feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoDebugAttr()); 1513d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1514d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 15151feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 15165bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 15175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 15185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 15195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 15205bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1522c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 15235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15245dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 15255bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 15265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1527bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15281feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoInlineAttr()); 15295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 15305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1531cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 153226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 153326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 153426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 153526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 153626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1537bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1538c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1539c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 154026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15415dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 154226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 154326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15450130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 1546cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1547c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1548c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 155040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) GNUInlineAttr()); 155126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 155226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1553ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1554ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1555ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 155655d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1557ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1558ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 155955d3aaf9a537888734762170823daf750ea9036dEli Friedman 1560ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1561ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1563ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1564ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 156555d3aaf9a537888734762170823daf750ea9036dEli Friedman 156655d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 156755d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 156855d3aaf9a537888734762170823daf750ea9036dEli Friedman if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 156955d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 157055d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 157155d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 157255d3aaf9a537888734762170823daf750ea9036dEli Friedman } 157355d3aaf9a537888734762170823daf750ea9036dEli Friedman 1574264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1575264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 157655d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 157755d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 157855d3aaf9a537888734762170823daf750ea9036dEli Friedman } 157955d3aaf9a537888734762170823daf750ea9036dEli Friedman 1580348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1581264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1582264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 158355d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 158455d3aaf9a537888734762170823daf750ea9036dEli Friedman } 158555d3aaf9a537888734762170823daf750ea9036dEli Friedman 158640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1587ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1588ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 1589bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1590bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // check the attribute arguments. 1591bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Attr.getNumArgs() != 0) { 1592bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1593bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1594bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1595bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1596bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isa<CXXRecordDecl>(d) 1597bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 1598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), 1599bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : diag::warn_attribute_wrong_decl_type) 1601bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt << Attr.getName() << 7 /*virtual method or class*/; 1602bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1603bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 16047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 16067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<FinalAttr>()) { 16087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 16097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 1611bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1612bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt d->addAttr(::new (S.Context) FinalAttr()); 1613bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1614bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 16150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 16167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes 16177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 16187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 16217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXRecordDecl>(d)) { 16267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 16277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 16287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 16297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 9 /*class*/; 16307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<BaseCheckAttr>()) { 16347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 16357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) BaseCheckAttr()); 16397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 16407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 16437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<RecordDecl>(d->getDeclContext())) { 16487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 16497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 16507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 16517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 16527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 11 /*member*/; 16537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 16577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<HidingAttr>()) { 16597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 16607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) HidingAttr()); 16647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 16657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 16687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 16737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 16747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 16757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 16767725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 16777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 10 /*virtual method*/; 16787725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 16827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<OverrideAttr>()) { 16847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 16857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 16867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 16877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt d->addAttr(::new (S.Context) OverrideAttr()); 16897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 16907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 16917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 1692b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 1693b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 1694b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1695b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1696b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 1697b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 16985dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17005dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 17015dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 17025dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 17035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 17045dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 170521531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 170621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 170721531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1708b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1709b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 1710bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17116217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1712183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall || RetTy->getAs<ObjCObjectPointerType>())) { 171321531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 171421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 171521531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName(); 1716bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 17175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 1718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1719b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 1720b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 1721b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 1722b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 172331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 172431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr()); 172531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 172631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 172731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr()); 172831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 1729b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 173040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1731b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1732b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 173340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1734b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1735b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 1736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 1737b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1738f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 1739f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 1740f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis Attr.getKind() == AttributeList::AT_dllexport; 1741f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 1742f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 1743b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 17440744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 17450744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 17460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1747a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1748803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1749bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 1750bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 1751bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 1752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 1753f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 1754f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // FIXME: Try to deal with other __declspec attributes! 1755290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 1756803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 175763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 175863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 1759803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1760ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 17616e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 1762bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 1764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 17657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 17667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1767bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 1768af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 1769b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 1770bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 17717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 17727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 1773bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 17747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 17757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 17767725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 17777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 17783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 17799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 17803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 17817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 17827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 17837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 17847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 17857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 17867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 17877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 17887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 17897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 17907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 17917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 1792b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1793b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 179431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 179531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 1796b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 1797b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 1798b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 1799b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 18006f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 18016f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 18026f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 18037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 18047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 18057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 18067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 18077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 18087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 1809026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1810026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 18117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 18127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 1813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1814803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1815803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 18160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 18170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 18180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 1819f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 18207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 18217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 18227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 18237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 18247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 18257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 18267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 18277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 18287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1829bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 18305e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 183105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 183205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 183304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 183404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 183504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 183604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall // These are all treated as type attributes. 183704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 1838803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 183982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 184082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 184182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 184282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1848803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 18499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 18519cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttribute(S, D, *AttrList, *this); 1852803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1853803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1856e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1857e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 18581eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 18597b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1860e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 1861e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1862e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1863e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 1864a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 1865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1867e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 1868a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 1869a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis VD->getStorageClass()); 1870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1871e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 1872e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1873e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 1874e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1875e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 18767b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1877c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 1878c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 1879c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1880c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 1881c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 18823d2c43e9a7ca55f5ddc1f0c77d8f5e5ea7c1b573Ted Kremenek NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName())); 1883c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NewD->addAttr(::new (Context) WeakAttr()); 1884c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 1885c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1886c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 1887c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 1888c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 1889c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 1890c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 1891c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 1892c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner ND->addAttr(::new (Context) WeakAttr()); 1893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1895e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 18960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 18970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 18980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 18999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1900e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Handle #pragma weak 1901e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1902e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (ND->hasLinkage()) { 1903e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1904e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W != WeakInfo()) { 19057b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn // Identifier referenced by #pragma weak before it was declared 19067b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn DeclApplyPragmaWeak(S, ND, W); 1907e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1908e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1909e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1910e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1911e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 19120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 19130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 19149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1915bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 19170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 19180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 19190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 19200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 19210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 19229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1923bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 19250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 19269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 19270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 192854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 192954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation 193054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings. 193154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// 193254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope 193354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack. 193454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallAction::ParsingDeclStackState Sema::PushParsingDeclaration() { 193554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth++; 19362f514480c448708ec382a684cf5e035d3a827ec8John McCall return (ParsingDeclStackState) DelayedDiagnostics.size(); 193754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 193854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 193954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) { 194054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 194154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth--; 194254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 19432f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics.empty()) 194454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 194554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 194654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall unsigned SavedIndex = (unsigned) S; 19472f514480c448708ec382a684cf5e035d3a827ec8John McCall assert(SavedIndex <= DelayedDiagnostics.size() && 194854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall "saved index is out of bounds"); 194954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 19502f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 19512f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 19522f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *D = Ctx ? Ctx.getAs<Decl>() : 0; 19532f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D) { 19542f514480c448708ec382a684cf5e035d3a827ec8John McCall // We really do want to start with 0 here. We get one push for a 19552f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 19562f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 19572f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 19582f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 19592f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 19602f514480c448708ec382a684cf5e035d3a827ec8John McCall for (unsigned I = 0, E = DelayedDiagnostics.size(); I != E; ++I) { 19612f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics[I].Triggered) 19622f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 19632f514480c448708ec382a684cf5e035d3a827ec8John McCall 19642f514480c448708ec382a684cf5e035d3a827ec8John McCall switch (DelayedDiagnostics[I].Kind) { 19652f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 19662f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 19672f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 19682f514480c448708ec382a684cf5e035d3a827ec8John McCall 19692f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 19702f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 19712f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 197254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 197354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 197454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 197554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 19762f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.set_size(SavedIndex); 19772f514480c448708ec382a684cf5e035d3a827ec8John McCall} 19782f514480c448708ec382a684cf5e035d3a827ec8John McCall 19792f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 19802f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 19812f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D->hasAttr<DeprecatedAttr>()) 19822f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 19832f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 19842f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 19852f514480c448708ec382a684cf5e035d3a827ec8John McCall} 19862f514480c448708ec382a684cf5e035d3a827ec8John McCall 19872f514480c448708ec382a684cf5e035d3a827ec8John McCallvoid Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD, 19882f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 19892f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 19902f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 19912f514480c448708ec382a684cf5e035d3a827ec8John McCall 19922f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 19932f514480c448708ec382a684cf5e035d3a827ec8John McCall Diag(DD.Loc, diag::warn_deprecated) 19942f514480c448708ec382a684cf5e035d3a827ec8John McCall << DD.DeprecationData.Decl->getDeclName(); 199554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 199654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 199754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 199854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 199954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (ParsingDeclDepth) { 20002f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 200154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 200254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 200354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 200454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 200554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 200654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 200754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 200854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 200954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 2010