SemaDeclAttr.cpp revision 2b0d9a247ab375ca316bf04feede73de6672fc31
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h" 156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 18fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 1912bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 20797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 27a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d, 28a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 30a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 32a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 34a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 38bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 41755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 426217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 43d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 44183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function 51a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) { 53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return getFunctionType(d, false) != NULL; 54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 59a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) { 60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return isFunction(d)|| isa<ObjCMethodDecl>(d); 61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 623568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 63620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 66a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) { 67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 70620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 74d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 75620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 77d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 79620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 81620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 8272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 83620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 84d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 91d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 92a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 9389951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 9472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 95d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 9789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 983568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 100a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 10189951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 103d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 104d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 105bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10689951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1073568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 109a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 115a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 116d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 11772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 119d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 120d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->IsVariadic(); 121d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1253568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 127183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 128b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 130bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 131183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAs<ObjCInterfaceType>(); 1326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 142085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 144085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 150bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 151085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 158e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 159e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 160e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 161e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1679cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 168545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 171545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1759cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(), 1819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Attr.getParameterName(), 1829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor false, 0, false).takeAs<Expr>(); 1839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor tDecl->setUnderlyingType(T); 197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 1999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 203065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 204bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleVectorSizeAttribute - this attribute is only applicable to integral 205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// and float scalars, although arrays, pointers, and function return values are 206bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// allowed in conjunction with this construct. Aggregates with this attribute 207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// are invalid, even if they are of the same size as a corresponding scalar. 208bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// The raw attribute should contain precisely 1 argument, the vector size for 209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// the variable, measured in bytes. If curType and rawAttr are well formed, 210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// this routine will return a new vector type. 211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 212065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 213065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 215065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 216065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 217065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 218fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 219fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 220065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 221065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 223065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 224545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 226065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 228545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 230803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 231fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << sizeExpr->getSourceRange(); 233065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 235bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // navigate to the base type - we need to provide for vector pointers, vector 236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arrays, and functions returning vectors. 237b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 238b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2392db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 2402db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner return; 2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 25382afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner // the base type must be integer or float, and can't already be a vector. 25482afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner if (CurType->isVectorType() || 25582afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 256d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 257065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 265fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 266fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 267065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 270fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 271fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 272065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 274bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 275065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 276065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 277803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 279065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 280065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump else 282065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 285803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 287545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 291bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 293a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson TD->addAttr(::new (S.Context) PackedAttr); 2946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 298803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 299fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 30008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 3016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 302a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson FD->addAttr(::new (S.Context) PackedAttr); 3036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 3043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 30896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 30996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 3103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 31296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 31496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 31596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 316327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 31740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) IBOutletAttr()); 31896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 319327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 32096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 32196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 323bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 324bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 325d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 326fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 331d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 341f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 345fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 348bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 349eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 35330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 357465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 361dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 363fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 364fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3657fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 366eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 369eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 371bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 372bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3737fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 37446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 37546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 376dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 377d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 37846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 379bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3817fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3827fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 384eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3857fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3887fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 38940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NonNullAttr(start, size)); 390eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 391eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 392803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 394545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 399545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 402bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 404fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 4053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 41440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 418af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 419af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 420af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 4213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 422af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 423af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 4245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 425c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 4265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 4285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 4295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 43140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlwaysInlineAttr()); 432af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 433af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 43476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 43576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn // check the attribute arguments. 43676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 43776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 43876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 43976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4412cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 4432cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 4442cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek d->addAttr(::new (S.Context) MallocAttr()); 4452cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 4462cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 447fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 448fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 4492cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 45076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 45176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 452b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 4535dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek Sema &S) { 4546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 455545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 457b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 4586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 459d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 46019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 46119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 46219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (VD == 0 || !VD->getType()->isBlockPointerType()) { 46319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 46519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump return false; 46619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 4676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 468bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 469b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 470b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 471b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 472b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 473bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 47440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoReturnAttr()); 475b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 476b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 477b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 478b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 479bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 48040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 4816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 48373798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 48473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 48573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 48773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 48873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 490d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 491fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 49373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 49473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 495bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 49640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnusedAttr()); 49773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 49873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 499b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 500b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 501b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 502b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 503b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 504b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 505bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 506b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 507186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 508b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 509b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 510b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 511b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 512b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5135dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 514b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 515b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 516bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 51740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UsedAttr()); 518b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 519b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 523fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 524fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 526bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 5273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 533fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 5353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 539bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 540c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 541fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 54640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstructorAttr(priority)); 5473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 553fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 5563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 562fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5633c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 5643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 568bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5696782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 570fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5715dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 57540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DestructorAttr(priority)); 5763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 578803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 580545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 5813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 58540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DeprecatedAttr()); 5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 588bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 589bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 590bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 591bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 592bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 593bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 59540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnavailableAttr()); 596bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 597bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 600545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 614bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 6226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 6256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 62808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 631bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 63240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) VisibilityAttr(type)); 6336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 6360db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 6370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 6380db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 6390db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6400db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 6430db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 6440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 6450db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 64840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr()); 6490db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 6500db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6510db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 652fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 653fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 654fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 655fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6560db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 657fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 658fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 6596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 660fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 661fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 662fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 663fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 66440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 665fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 666fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 668f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 669f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 670f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 671f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 672f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 673f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 674f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 675f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 676f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 677f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 678f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 67940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr()); 680f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 681f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 684fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 69592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6969eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 698fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6993c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 7009eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 7019eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 70340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) BlocksAttr(type)); 7049eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 7059eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 707770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 708770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 709fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 710fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 717770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 719fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 724bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 726fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 728770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 729770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 730770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 731770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 732770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 734770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 735770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 736770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 737fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 739770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 740770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 741770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 743770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 744770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 745770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 746fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 747fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 748770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 749770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 750770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 751770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 752770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 753183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 754897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 755bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 756897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 757897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 758897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 759897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 760bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 761897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7623bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 763770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 765770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 766770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 7673bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 768770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 7692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7702f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 771bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 772bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 7732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 7742f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 7752f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 776daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 777bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 778183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 7792f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7803bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 7813bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 7822f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7832f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 784ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 7852f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 786ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 7872f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7882f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 790fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 791ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 792770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 79440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 795770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 797026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 798026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 799026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 800026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 801026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 802026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 803026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 804026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // TODO: could also be applied to methods? 805026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 806026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (!Fn) { 807026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 809026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 810026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 811bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 81240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 813026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 814026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 815026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 817545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 822f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 823f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian bool isStatic = false; 824f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 825f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = VD->getStorageClass() == VarDecl::Static; 826f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 827f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = FD->getStorageClass() == FunctionDecl::Static; 828f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 829f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (isStatic) { 830f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 831f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 832f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 833f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 834f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 8356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 8366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 8376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8385dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 84240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakAttr()); 8436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 8476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 8486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 8516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 8536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 8546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 8556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 8566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 8576fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis isDef = FD->getBody(); 858d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 859d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 8601c90f4dc686ab872013544664c797604a309c563Mike Stump return; 8616e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else { 8626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8635dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8656e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 8686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 8706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 8716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 8726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8746e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 87540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr()); 8766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 8776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 878026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 880545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8847b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8852f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 886026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 88740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLImportAttr()); 8882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8892f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8902f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 891026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 8922f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 8932f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8945dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8952f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8962f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8972f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8982f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllimport attribute is ignored for inlined functions. 8992f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 9002f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 9012f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 9022f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9032f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9042f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 9052f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // The attribute is also overridden by a subsequent declaration as dllexport. 9062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 9072f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 9082f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov nextAttr = nextAttr->getNext()) { 9092f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (nextAttr->getKind() == AttributeList::AT_dllexport) { 9102f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 9112f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9122f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9132f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9142f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 91540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (D->getAttr<DLLExportAttr>()) { 9162f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 9172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 92040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLImportAttr()); 9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 923026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 9246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 925545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9297b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 931026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 93240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLExportAttr()); 9332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 936026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 9372f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 9382f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 9402f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9412f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9422f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 943bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Currently, the dllexport attribute is ignored for inlined functions, unless 944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // the -fkeep-inline-functions flag has been used. Warning is emitted; 9452f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 9462f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // FIXME: ... unless the -fkeep-inline-functions flag has been used. 9472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 9482f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9492f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 95140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLExportAttr()); 9526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 9556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 9566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 9576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 9586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 9596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 9606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 9616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 9626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 9636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 9646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Expr *E = static_cast<Expr *>(Attr.getArg(i)); 9656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 9666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 9676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 9686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 9696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 9706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 9716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 9726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 97340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 9746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 9756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 9766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 977026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 97817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 97917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 98017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 98117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 98217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 98317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 98417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 98517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 986797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 987797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 98817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 989797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 99017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 99117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 993797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner std::string SectionStr(SE->getStrData(), SE->getByteLength()); 994797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner 995797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 996797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr); 997797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner if (Error.empty()) { 998797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner D->addAttr(::new (S.Context) SectionAttr(SectionStr)); 999797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1000797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 10011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1002797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1003797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner << Error; 10041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 100517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 100617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 1007803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 1009545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10137b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10147b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute can be applied only to functions. 10157b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 10167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10187b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10197b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10207b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10217b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 102240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (d->getAttr<FastCallAttr>()) { 10237b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 10247b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "fastcall"; 10257b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10267b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10277b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 102840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) StdCallAttr()); 10296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1031803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10327b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 1033545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10377b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10387b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 10397b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10405dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10417b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10427b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10437b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 104540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (d->getAttr<StdCallAttr>()) { 10467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 10477b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "stdcall"; 10487b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 105140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FastCallAttr()); 10526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1054803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1056545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 106140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoThrowAttr()); 10626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1064232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1065232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1066232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1068232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1069232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1070bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 107140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstAttr()); 1072232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1073232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1074232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1075232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1076232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1078232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1079232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 108140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) PureAttr()); 1082232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1083232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 108589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // Match gcc which ignores cleanup attrs when compiling C++. 108689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (S.getLangOptions().CPlusPlus) 108789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 1088bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1091f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1092f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1093bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1094f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1095f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1096f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1097f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1098bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1099f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1100bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1101f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1102f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1103f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1104f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1105bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1106f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1107f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1108f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1109f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall Sema::LookupOrdinaryName); 1110f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 111189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1112f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1113f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1114f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1116f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1117f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 111889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1119f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1120f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1121f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1122f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1123f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 112489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1126f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1127f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 112989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 113089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 113189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 113289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1133d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 113589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 113689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 113789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 113889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 114040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CleanupAttr(FD)); 1141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1142f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 11475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 11505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 11515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 11525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 11535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start with 1. 11575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned NumArgs = getFunctionOrMethodNumArgs(d); 11585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 11595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 11605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 11615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 11625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 11635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 11655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 11695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 11715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 11775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 11805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 11815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 11825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 11836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 11845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 11855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 11875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 11885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 11905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 11915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 11925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 11935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 11946217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 11955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 11965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 11985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 11995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 120240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 12035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 12045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 12052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 12062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 12072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 12082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 12092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 12102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 12112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 12122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 12132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 12142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 12152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 12162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 12172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 12182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 12192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 12202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 12212b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 12222b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 12232b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 12242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 12252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 12262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 12272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 12282b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 12292b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 12302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 12312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 12322b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 12332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1235bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1236803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1238545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 12403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1244545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 12453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 12466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1249620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1250fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12515dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 12526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getNameStr(); 12596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 12612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 12622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 12632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 12642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 12652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 12662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1267fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 12682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar << "format" << Attr.getParameterName()->getNameStr(); 12696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1273545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1274803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1275803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1276fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 12786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12814fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // FIXME: We should handle the implicit 'this' parameter in a more generic 12824fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // way that can be used for other arguments. 12834fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson bool HasImplicitThisParam = false; 12844fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 12854fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (MD->isInstance()) { 12864fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson HasImplicitThisParam = true; 12874fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson NumArgs++; 12884fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 12894fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 12901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1292fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 12933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 12946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 12986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1299bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13004fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (HasImplicitThisParam) ArgIdx--; 13011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 13033568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 13046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1306085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1307fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1308fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1309085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1310085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 13112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1312390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1313390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1315390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1316fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 13206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 13216217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1322390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1323fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1324fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 13256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1329545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1330803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1331803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 13333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 13393568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 13406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1342803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 13436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 13483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 13492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 13506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 13536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 13566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 13583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 13596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar d->addAttr(::new (S.Context) FormatAttr(Format, Idx.getZExtValue(), 13632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 13646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 13670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 13686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1369545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 13703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 13750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1376bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 13770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 13780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 13790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 13800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 13810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 13820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1383fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 13845dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 13856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1389bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 13900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 13910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 13920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 13930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 139417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 139517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 13960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 13970c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 13980c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 13990c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1400bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 14010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 14020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 14030c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 14050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_floating); 14060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 14070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1408bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 14090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 14100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 14110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 14120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 14130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 14140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 14150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 14160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1417bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 14180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 14200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 14210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 14220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1423bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 14240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 14250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1426bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1427bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1428bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 14296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 143040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr()); 14316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 14326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1435545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 14363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 14376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1439797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1440797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1441bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 14436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 14446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1445797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 14466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 144840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 14490b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 14506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 14516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1454545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 14553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 14566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1460545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 14616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 14627549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 146440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Align)); 14656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1467bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 146849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 146949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1470803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1472fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 147349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 147449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1475396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1476bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1477396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar << alignmentExpr->getSourceRange(); 1478396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1479396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1480396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 148140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 14826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1484bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1487bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 14900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1495fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 14963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1501fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 15020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1503fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1504fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1505fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1506fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1507fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1508fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1509fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1510fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1511fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1512fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1513fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1514fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1515fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1516fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 151773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1518fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1519fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 152073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 152173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 152273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 152373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 152473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 152573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 152673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 152773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 152873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 152973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 153073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 153173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 153273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 153373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 153473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 153573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1536fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1537fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1538fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1539fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1540fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 15410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1542fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 15430b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1544fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1545fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1546fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 15470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1548fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1550fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1551fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1553fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1554fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1555fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1557fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1558fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1559fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1560fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 156173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1562183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 156373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 156473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 156573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isIntegralType()) 156673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 156773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 156873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 156973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 157073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 157173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 157273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 157373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 157473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1575390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1576390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1577390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1578390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1579f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1580f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1583fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 15843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1586fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 15873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1588fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 159073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 159173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 159273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 159373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1594fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 15950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1596fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 15970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1598fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 160073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 160173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 160273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 160373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 16050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1606fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 16070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1609fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1610fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 16110b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 16130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1614fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 16150b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1616fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1617fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1618fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 16190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1620fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 16210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1622fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 16230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1624fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 162573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 162673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 162773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1628f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1629f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1630f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1631f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1632f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1633f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 163473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1635fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1636fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 163773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 163873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1639fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1640fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1642fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1643fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1644fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1646fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 16470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 16481feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1649d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1650d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1651d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1652d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1653d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1654e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 16555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1656d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16575dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1658d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1659d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1660bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16611feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoDebugAttr()); 1662d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1663d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 16641feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 16665bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 16675bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 16695bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1671c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 16725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 16745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 16755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16771feade8e520be483293dbf55eb57a51720899589Mike Stump d->addAttr(::new (S.Context) NoInlineAttr()); 16785bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 16795bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1680cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 168126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 168226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 168326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 168426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 168526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1686bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1687c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1688c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 168926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 169126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 169226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1694c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!Fn->isInline()) { 1695cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1696c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1697c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1698bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 169940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) GNUInlineAttr()); 170026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 170126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1702ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1703ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1704ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 170555d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1706ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1707ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 170855d3aaf9a537888734762170823daf750ea9036dEli Friedman 1709ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1710ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 17115dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1712ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1713ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 171455d3aaf9a537888734762170823daf750ea9036dEli Friedman 171555d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 171655d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 171755d3aaf9a537888734762170823daf750ea9036dEli Friedman if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 171855d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 171955d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 172055d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 172155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 172255d3aaf9a537888734762170823daf750ea9036dEli Friedman 1723264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1724264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 172555d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 172655d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 172755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 172855d3aaf9a537888734762170823daf750ea9036dEli Friedman 1729348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1730264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1731264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 173255d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 173355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 173455d3aaf9a537888734762170823daf750ea9036dEli Friedman 173540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1736ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1737ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 17380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 1739b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 1740b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 1741b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1742b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1743b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 1744b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 17455dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 1746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 17485dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 17495dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 17505dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 17515dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 175221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 175321531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 175421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 1755b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1756b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 1757bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 1759183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall || RetTy->getAs<ObjCObjectPointerType>())) { 176021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 176121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 176221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName(); 1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 17645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 1765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1766b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 1767b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 1768b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 1769b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1770b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 177140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1772b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1773b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 177440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1775b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1776b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 1777b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 1778b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1779b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 17800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 17810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 17820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1783a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1784803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1785803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1786bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 1787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 1788290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman if (Attr.isDeclspecAttribute()) 1789290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman // FIXME: Try to deal with __declspec attributes! 1790290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 1791803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 17923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1794ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 1795bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 1796bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 1797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1798803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 17993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 1801af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 1802b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 1803bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 18043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 18053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 18073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 18093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 18103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 18119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 18123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1814803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 18155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1816cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 18173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 181876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 1819eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 18203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 18213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1822b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1823b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 1824b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 1825b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 1826b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 1827b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 18286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 18296f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 18306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 18313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 183217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 18333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1834bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 183573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1836b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 18373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 18383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1839026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1840026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 18413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 18426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1844803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 18460db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 18470db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 18480db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 1849f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1850fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 18519eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1852770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1853232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1854232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1855f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 18561feade8e520be483293dbf55eb57a51720899589Mike Stump case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 18571feade8e520be483293dbf55eb57a51720899589Mike Stump case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 185855d3aaf9a537888734762170823daf750ea9036dEli Friedman case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 18605e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 186105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 186205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 1863803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1864d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1866803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1867803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1868803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1869803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1870803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 18719cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1872803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 18739cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttribute(S, D, *AttrList, *this); 1874803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1875803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1876803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1877803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1878e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1879e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 18801eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 18817b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1882e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 1883e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1884e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 1886a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis FD->getType(), FD->getDeclaratorInfo()); 1887e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1888e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1889e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 1890a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis VD->getType(), VD->getDeclaratorInfo(), 1891a1d5662d96465f0fddf8819d245da4d19b892effArgyrios Kyrtzidis VD->getStorageClass()); 1892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 1894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1895e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 1896e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1897e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 18987b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 1899c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 1900c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 1901c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1902c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 1903c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1904c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 1905c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NewD->addAttr(::new (Context) WeakAttr()); 1906c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 1907c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 1908c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 1909c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 1910c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 1911c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 1912c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 1913c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 1914c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner ND->addAttr(::new (Context) WeakAttr()); 1915e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1916e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1917e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 19180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 19190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 19200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 19219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1922e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Handle #pragma weak 1923e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1924e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (ND->hasLinkage()) { 1925e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1926e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W != WeakInfo()) { 19277b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn // Identifier referenced by #pragma weak before it was declared 19287b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn DeclApplyPragmaWeak(S, ND, W); 1929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1931e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1932e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1933e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 19340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 19350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 19369cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1937bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 19390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 19400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 19410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 19420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 19430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 19449cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1945bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 19470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 19489cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 19490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 1950