SemaDeclAttr.cpp revision 9c3087b0b0bea2fd782205c1274ebfc4290265e0
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 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 18acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 20fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 229c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 23797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 28e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 29e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 30e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 31a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d, 32a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 34a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 36a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 38a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 42bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 45755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 47d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 48183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 54d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) { 57a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return getFunctionType(d, false) != NULL; 58a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 59a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 60a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 63a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) { 64a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return isFunction(d)|| isa<ObjCMethodDecl>(d); 65d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 70a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) { 71620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 73620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 75620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 77620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 78d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 79620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 80620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 83620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 85620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 8672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 87620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 88d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 93d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 94d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 95d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 96a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 9789951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 9872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 99d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 100d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 10189951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 1023568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1033568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 104a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 10589951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 107d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 108d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11089951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1113568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1123568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 113a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 119a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 12172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 123d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 124db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 125d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1263568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1273568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1283568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 131183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 132b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 135506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 136506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 139506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1516217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 154bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 156465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 157085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 160085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 162e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 163e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 164e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 165e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1719cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 173545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 175545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 184f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 185f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 186f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 187f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 1999ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 2009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 201ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 202a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 211545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 217cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 223fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 22408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 226cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 23296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 23396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 23596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 23696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 237bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 23963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 24063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 241cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 24263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 24363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 24763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 25463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 256efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 257efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 258cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 260efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 26263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 26396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 26496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 265857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 266857e918a8a40deb128840308a318bf623d68295fTed Kremenek Sema &S) { 267857e918a8a40deb128840308a318bf623d68295fTed Kremenek 268857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 269a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 270857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 271857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 272857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 273857e918a8a40deb128840308a318bf623d68295fTed Kremenek 274857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 275857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 276857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 277857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 278857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 279857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 2803a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 2813a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 2823a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 2833a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << VD->getType() << 0; 2843a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 2853a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 2863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 2873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 2883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 2893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << PD->getType() << 1; 2903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 2913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 2923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 293a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 294a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 295a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian II = &S.Context.Idents.get("id"); 2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 297b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 298a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.getScopeForContext(d->getDeclContext()->getParent())); 299a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 300a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 301a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 302a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 303b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 304a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 305a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCClassType() && 309a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian !QT->isObjCObjectType()) { 310a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 313cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 314cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt QT)); 315857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 316857e918a8a40deb128840308a318bf623d68295fTed Kremenek 317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 318bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 319bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 320d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 321fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3225dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 326d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 333bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 334bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 336f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 338ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 339ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 340fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 348fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 34930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 353465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 357dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 359c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 360fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 363bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3697fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 37046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 37146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 372dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 373d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 37446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 375bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3767fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3777fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3787fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3797fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 380eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3817fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3827fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 384dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 385cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 386cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 387eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 388eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 389dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 390dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 391dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 392dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 393dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 394dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 395dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 3962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 3972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 398dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 399dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 400dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 401dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 402dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 403dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 404dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 405cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 4062a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 4072a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 408cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 409dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 410dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 411dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 412dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4132a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 415cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 416dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 417dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 418dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 419dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4202a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4212a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 422cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 423dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 424dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 425dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 427dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4282a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4292a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 4302a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 4312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 432dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!isFunction(d) || !hasFunctionProto(d)) { 435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << 0 /*function*/; 437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 438dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned NumArgs = getFunctionOrMethodNumArgs(d); 441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 442dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::StringRef Module = AL.getParameterName()->getName(); 443dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 448dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::SmallVector<unsigned, 10> OwnershipArgs; 449dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 4502a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 4512a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Expr *IdxExpr = static_cast<Expr *>(*I); 454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 455dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 456dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 457dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 463dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 464dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 471cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 472cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek QualType T = getFunctionOrMethodArgType(d, x); 475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 477dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 478cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 485cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0)); 489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 5002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 5012a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 505cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 506cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i = d->specific_attr_begin<OwnershipAttr>(), 507cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt e = d->specific_attr_end<OwnershipAttr>(); 508cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 509cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 510cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 511cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 512cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 513cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 514cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 515dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 516dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 518dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 519dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 525cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 526cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 527cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 528cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 530cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 531cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 53511e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) { 53611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (VarDecl *VD = dyn_cast<VarDecl>(D)) 53711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return VD->getStorageClass() == VarDecl::Static; 53811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 53911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return FD->getStorageClass() == FunctionDecl::Static; 54011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 54111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 54211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 54311e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 54411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 54511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 54611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 54711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 54811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 54911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 55011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 55111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 55211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 55311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 55411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 55511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 55611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 55711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 55811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 55911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 56011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (const DeclContext *Ctx = d->getDeclContext()) { 56111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Ctx = Ctx->getLookupContext(); 56211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) { 56311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 564dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(d)->getNameAsString(); 56511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 56611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 56711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 56811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 56911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 57011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 57111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 57211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 57311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 57411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 57511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 57611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 57711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 57811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 57911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 58011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 58111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 58211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 58311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 58411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 58511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 58611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 58711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (!isStaticVarOrStaticFunciton(d)) { 58811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 58911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola dyn_cast<NamedDecl>(d)->getNameAsString(); 59011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 59111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 59211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 59311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 59411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 59511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 59611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 59711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 59811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 59911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 60011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 60111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 60211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Str == 0 || Str->isWide()) { 60311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 60411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 60511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 60711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 60811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 609cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString())); 61011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 61111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 612cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 615803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 617545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 621bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 622545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 6246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 625bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 627fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 631bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 633bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 634cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString())); 6356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 638af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 639af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 640af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 6413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 642af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 643af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 6445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 645c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 6465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 6475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 6485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 6495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 650bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 651cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 652af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 653af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 65476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 65576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn // check the attribute arguments. 65676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 65776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 65876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 65976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6612cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 6632cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 664cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 6652cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 6662cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 667fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 668fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 6692cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 67076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 67176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 672b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 673b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 674b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek assert(Attr.isInvalid() == false); 675b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context)); 676b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 677b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 678b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 679b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek Sema &S) { 680b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 681b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 682b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 683b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 684545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 685e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 686b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 688b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 68919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 69019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 6913ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 6923ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 693e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 694e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 695b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 696b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek << Attr.getName() << 0 /*function*/; 697b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 69819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 700b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 701b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 70435cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 70535cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 70635cc9627340b15232139b3c43fcde5973e7fad30John Thompson Sema &S) { 70735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 70835cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 70935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 71035cc9627340b15232139b3c43fcde5973e7fad30John Thompson According to the PPU ABI specifications, a class with a single member of vector type is returned in 71135cc9627340b15232139b3c43fcde5973e7fad30John Thompson memory when used as the return value of a function. This results in inefficient code when implementing 71235cc9627340b15232139b3c43fcde5973e7fad30John Thompson vector classes. To return the value in a single vector register, add the vecreturn attribute to the class 71335cc9627340b15232139b3c43fcde5973e7fad30John Thompson definition. This attribute is also applicable to struct types. 71435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 71535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 71635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 71735cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 71835cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 71935cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 72035cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 72135cc9627340b15232139b3c43fcde5973e7fad30John Thompson 72235cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 72335cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 72435cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 72535cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 72635cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 72735cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 72835cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 72935cc9627340b15232139b3c43fcde5973e7fad30John Thompson if (!isa<CXXRecordDecl>(d)) { 73035cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 73135cc9627340b15232139b3c43fcde5973e7fad30John Thompson << Attr.getName() << 9 /*class*/; 73235cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 73335cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 73435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 73535cc9627340b15232139b3c43fcde5973e7fad30John Thompson if (d->getAttr<VecReturnAttr>()) { 73635cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 73735cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 73835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 73935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 740cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 74135cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 74235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 743bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 744bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 745bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 74604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall << Attr.getName() << 8 /*function, method, or parameter*/; 747bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 748bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 749bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 750bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 751bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 75273798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 75373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 75473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 7553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 75673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 75773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 759aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 760aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall !isa<TypeDecl>(d)) { 761fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 76373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 76473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 766cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 76773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 76873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 769b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 770b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 771b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 772b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 773b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 774b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 776b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 777186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 778b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 779b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 780b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 781b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 782b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 784b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 785b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 786bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 787cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 788b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 789b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 7903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 7923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 793fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 794fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 7953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 796bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 7973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 7983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 7993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 8003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 8013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 802ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 803ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 804fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 8053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 8063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 8073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 8083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 8093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 810bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 811c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 812fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8135dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 8143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 8153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 8163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 817cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority)); 8183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 8193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 8203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 8223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 823fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 824fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 8253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 8273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 8283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 8293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 8303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 8313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 832ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 833ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 834fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 8353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 8363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 8373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 8383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 8393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 840bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 8416782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8435dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 8443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 8453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 8463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 847cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority)); 8483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 8493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 852545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 857cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context)); 8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 860bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 861bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 862bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 863bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 864bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 865bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 866bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 867cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context)); 868bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 869bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 870803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 872545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 8733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 8746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 877545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 880bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 8816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 882fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 8833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 8846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 887c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 888cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 890c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 891cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 892c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 893cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 894c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 895cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 896c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 897cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 8986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 89908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 9006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 903cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 9046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 9070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 9080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 9090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 9110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 9140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 9150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 9160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 9170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 919cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 9200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 9210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 9220db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 923fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 9242b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 925fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 926fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 9270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 928fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 929fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 9306217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 931fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 932fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 933fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 934fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 935cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 936fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 937fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 938bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 939f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 940f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 9412b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 942f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 943f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 944f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 945f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 946f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 947f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 948f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 949f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 951f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 952f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 9539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 955fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 9563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 9579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 959bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9609eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 9613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 9629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 964bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 965cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 96692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 9679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 9689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 969fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 9703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 9719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 9729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 9759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 9769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 977770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 978770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 979770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 980fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 981fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 982770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 983bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 984bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 985770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 986770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 987770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 988770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 989ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 990ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 991fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 993770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 994770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 995770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 996bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 997770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 998fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 999fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1000770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1001770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1002770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1003770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1004770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 1005770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 1006770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 1007770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1008ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1009ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1010fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1012770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1013770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1014770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1015bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1016770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 1017770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1018770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1019fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1020fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1021770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1022770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1023770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1024770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1025770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1026183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1027897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 1028bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1029897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1030897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1031897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1032897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1033bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1034897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 10353bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1036770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1038770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1039770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 10403bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1041770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 10422f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 10432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 1044bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1045bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 10462f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 10472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 10482f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1049daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1050bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1051183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 10522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 10533bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 10543bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 10552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 10562f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1057ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 10582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1059ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 10602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 10612f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1062770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1063fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1064ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 1065770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1066770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1067cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos)); 1068770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1069770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1070026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1071026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 1072026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 1073026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1074026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1075026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1076026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1077f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1078026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1080026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1081026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1082bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1083f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1084f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1085f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1086f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1087f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1088f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1089f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1090f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1091f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1092f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1093f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1094f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1095cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1096026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1097026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1098026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1100545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 11013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1105f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 110611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (isStaticVarOrStaticFunciton(D)) { 1107f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1108f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 1109f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1110f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1111f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 11126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 11136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 11146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 11155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 11166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 11176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1119cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 11206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 11236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 11246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 11256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 11266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 1127bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 11286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 11296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 11306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 11316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 11326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 11336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 113406a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis isDef = FD->hasBody(); 1135d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1136d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 11371c90f4dc686ab872013544664c797604a309c563Mike Stump return; 11385f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1139c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian // Don't issue the warning for darwin as target; yet, ignore the attribute. 11403be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1141c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian !isa<ObjCInterfaceDecl>(D)) 1142c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 11433be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian << Attr.getName() << 2 /*variable and function*/; 11443be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian return; 11456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 11466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 11476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 11486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 1149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 11506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 11516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 11526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 11536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 11546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 11566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 11576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 11586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 11596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 11606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 11616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 11622b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 11646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 11656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 11666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 11676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 11686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Expr *E = static_cast<Expr *>(Attr.getArg(i)); 11696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1170ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1171ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 11726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 11736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 11746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 11756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 11766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 11776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1179cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 11806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 11816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 11826f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 1183026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 118417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 118517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 118617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 118717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 118817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 118917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 119017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 119117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 1192797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1193797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 119417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1195797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 119617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 119717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 11981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1199797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1200bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1201a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1202a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1203a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1204797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1205797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 12061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1207a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1208a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1209a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1210a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1211a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1212a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 1213cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString())); 121417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 121517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1217803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1219545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 12203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1224cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1227232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1228232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1229232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 12303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1231232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1232232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1233bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1234cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1235232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1236232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1237232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1238232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1239232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 12403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1241232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1242232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1244cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1245232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1246232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1247f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1249f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1250f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1251f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1253f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1254f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1255f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1256f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1258f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1259bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1260f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1261f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1262f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1263f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1265f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1266c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 1267c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: The lookup source location should be in the attribute, not the 1268c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // start of the attribute. 1269f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1270c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor = S.LookupSingleName(S.TUScope, Attr.getParameterName(), Attr.getLoc(), 1271f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall Sema::LookupOrdinaryName); 1272f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 127389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1274f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1275f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1276f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1277bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1278f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1279f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 128089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1281f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1282f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1283f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1284f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1285f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 128689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1287f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1288f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1289f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 129189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 129289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 129389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 129489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1295d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1296bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 129789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 129889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 129989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 130089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1301bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1302cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1303f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1304f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1305bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1306bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1307bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 13095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 13115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 13125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 13135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 13145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 13155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 13165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1318bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start with 1. 13195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned NumArgs = getFunctionOrMethodNumArgs(d); 13205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 13215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 13225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 13235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 1324ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1325ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 13265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 13275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 13285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 13295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 13325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 13335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 13345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 13355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1336bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 13405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 13435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 13445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 13455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 13466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 13475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 13485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 13505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 13515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 13535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 13545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 13555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 13565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 13576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 13585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 13595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 13615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 13625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1363bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1364bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1365cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue())); 13665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 13675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 13682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 13692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 13702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 13712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 13722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 13733c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 13742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 13752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 13762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 13772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 13782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 13792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 13802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 13812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 13822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 13832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 13842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 13852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 13862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 13872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 13882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 13892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 13902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 13912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 13922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 13932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 13942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1395bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1396bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 13973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 13983c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 13992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 14002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 14012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1402521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 1403521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1404521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1405521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Sema &S) { 1406521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 1407521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1408521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1409521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1410521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1411b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1412b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1413b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1414b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1415b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1416b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian QualType T = dyn_cast<VarDecl>(d)->getType(); 1417b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 1418b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 1419b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 1420b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1421b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1422b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1423b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1424b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1425521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 1426521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1427521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1428521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1429521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1430521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0)); 1431b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1432521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 1433521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1434521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1435521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1436521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 1437521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1438521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1439521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 14409f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 1441521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 1442521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1443521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 1444521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1445521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1446521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1447cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum)); 1448521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 1449521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1450bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1454545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1455fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 14563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 14576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1460545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 14613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 14626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1465620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1466fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 14675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 14686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14713568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 14726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 14736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 147401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 14756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 14772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 14782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 14792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 14802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 14812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 14823c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 14833c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 14843c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 14853c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 14862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1487fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 148801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 14896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1494803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1495ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1496ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1497fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 14996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15024fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // FIXME: We should handle the implicit 'this' parameter in a more generic 15034fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson // way that can be used for other arguments. 15044fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson bool HasImplicitThisParam = false; 15054fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(d)) { 15064fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson if (MD->isInstance()) { 15074fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson HasImplicitThisParam = true; 15084fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson NumArgs++; 15094fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 15104fb77202ceef22a572cf4357f380b08f6bcc5c36Anders Carlsson } 15111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1513fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 15143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 15156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 15196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15214a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 15224a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 15234a2614e94672c47395abcde60518776fbebec589Sebastian Redl S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 15244a2614e94672c47395abcde60518776fbebec589Sebastian Redl << "a string type" << IdxExpr->getSourceRange(); 15254a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 15264a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 15274a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 15284a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 15291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 15313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 15326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1534085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1535fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1536fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1537085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1538085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 15392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1540390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1541390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1542803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1543390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1544fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1545fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 15466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1547bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 15496217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1550390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1551fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 15536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1557545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1558803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1559ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1560ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1561fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 15636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 15676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 15683568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 15696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 15706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1571803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 15726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 15773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 15782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 15796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1580fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1581fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 15826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 15856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1586fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 15873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 15886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 15906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1591cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1592cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 15932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 15946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 15970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 15986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1599545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 16003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 16050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1606bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 16070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 16080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 16090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 16100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 16110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 16120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1613fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16145dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 16156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1619bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 16200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 16210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 16220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 16230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 162417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 162517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 16260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 16270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 16280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 16290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1630bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 16310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 16320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 163390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1634bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 163590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 163690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 16370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 16380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1639bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 16400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 16410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 16420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 16430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 16440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 16450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 16460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 16470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1648bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 16490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1650bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 16510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 16520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 16530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1654bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 16550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 16560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1657bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1658bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1659bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 16606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1661cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 16626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1666545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 16673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1670797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner Expr *ArgExpr = static_cast<Expr *>(Attr.getArg(0)); 1671797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1672bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 16756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1676797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 16776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1679cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString())); 16806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16824ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 16836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1684545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 16853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1688bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1689bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1690bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1691bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 16926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1693545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 1694cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 16954ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 16964ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 16974ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 16984ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0))); 16994ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 17004ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 17014ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 17024ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 17034ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 1704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 17056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1708cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 170949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 17104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 17114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 17124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 171349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 171449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1715396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 17164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 17174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 1718396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1719396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1720396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 1721cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1722cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 1723cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1724cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1725cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 1726cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 1727cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1728cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 17296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1731bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1733fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1734bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1735bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1736bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 17370b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1738fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1739fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 17433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1745fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 17490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1750fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1752210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 175301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 1754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1756210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 1757210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 1758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1760fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 176173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1762210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 1763fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 176473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 176573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 176673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 176773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 176873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 176973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 177073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 177173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 177273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 177373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 177473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 177573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 177673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 177773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 177873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 177973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1781fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1784210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 17850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1786210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 17870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1789fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1790210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 17910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1792fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1793fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1794fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1796fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1797fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1798fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1799fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1801fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1802fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1804fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 180573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1806183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 180773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 180873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 18092ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 181073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 181173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 181273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 181373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 181473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 181573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 181673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 181773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 181873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1819390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1820390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1821390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1822390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1823f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1824f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1826fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1827fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 18283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1829fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1830fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 18313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1832fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1833fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 183473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 183573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 183673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 183773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1838fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 18390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1840fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 18410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1842fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1843fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 184473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 184573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 184673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 184773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1848fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 18490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1850fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 18510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1852fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1853fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1854fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 18550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1856fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 18570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1858fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 18590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1860fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1861fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1862fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 18630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1864fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 1865aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1866aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 1867aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1868aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 1869fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1870aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 1871aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 1872aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 1873aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 1874fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 187573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 187673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 187773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1878f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1879f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1880f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1881f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1882f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1883f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 1884f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 1885f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 1886f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 188773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1888fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1889fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 189073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 189173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1892fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1893fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1894fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1895ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1896ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 1897a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 1898ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 1899fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1900fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 19010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 19021feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1903d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1904d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1905d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1906d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1907d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1908e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 19095bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1910d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19115dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1912d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1913d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1914bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1915cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 1916d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1917d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 19181feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 19195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 19205bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 19215bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 19235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1924bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1925c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 19265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 19285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 19295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1931cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 19325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 19335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 19347255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 19357255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner Sema &S) { 19367255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 19377255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (Attr.getNumArgs() != 0) { 19387255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19397255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 19407255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 19417255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 19427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (!isa<FunctionDecl>(d)) { 19437255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner << Attr.getName() << 0 /*function*/; 19457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 19467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 19477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 1948cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context)); 19497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 19507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 1951cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 195226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 195326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 195426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 195526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 195626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1958c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1959c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 196026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 19615dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 196226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 196326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1964bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19650130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 1966cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1967c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1968c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1969bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1970cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 197126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 197226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1973e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1974e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // Diagnostic is emitted elsewhere: here we store the (valid) Attr 1975e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 1976e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara assert(Attr.isInvalid() == false); 1977e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 1978e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara switch (Attr.getKind()) { 1979e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 1980cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 1981e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1982e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 1983cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 1984e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1985f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 1986cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 1987e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 1988cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 1989e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1990e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 1991e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 1992e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 1993e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 1994e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 1995e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 1996ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1997ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1998ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 199955d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2000ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2001ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 200255d3aaf9a537888734762170823daf750ea9036dEli Friedman 2003ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 2004ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 20055dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 2006ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2007ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 200855d3aaf9a537888734762170823daf750ea9036dEli Friedman 200955d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 201055d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 2011ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2012ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 201355d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 201455d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 201555d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 201655d3aaf9a537888734762170823daf750ea9036dEli Friedman } 201755d3aaf9a537888734762170823daf750ea9036dEli Friedman 2018264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 2019264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 202055d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 202155d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 202255d3aaf9a537888734762170823daf750ea9036dEli Friedman } 202355d3aaf9a537888734762170823daf750ea9036dEli Friedman 2024348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 2025264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2026264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 202755d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 202855d3aaf9a537888734762170823daf750ea9036dEli Friedman } 202955d3aaf9a537888734762170823daf750ea9036dEli Friedman 2030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, 2031cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NumParams.getZExtValue())); 2032ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 2033ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 2034bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2035bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // check the attribute arguments. 2036bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Attr.getNumArgs() != 0) { 2037bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2038bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 2039bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2040bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2041bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isa<CXXRecordDecl>(d) 2042bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 2043bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), 2044bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2045bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : diag::warn_attribute_wrong_decl_type) 2046bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt << Attr.getName() << 7 /*virtual method or class*/; 2047bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 2048bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 20497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 20517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<FinalAttr>()) { 20537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 20547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 2056bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2057cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); 2058bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 2059bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 20600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 20617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes 20627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 20637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 20667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXRecordDecl>(d)) { 20717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 20727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 20737725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 20747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 9 /*class*/; 20757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20767725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20777725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20787725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<BaseCheckAttr>()) { 20797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 20807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context)); 20847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 20857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 20887725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20897725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 20917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 20927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<RecordDecl>(d->getDeclContext())) { 20937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 20947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 20957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 20967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 20977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 11 /*member*/; 20987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 20997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 21007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 21027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<HidingAttr>()) { 21047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 21057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 21067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 21077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2108cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context)); 21097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 21107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 21127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 21137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 21147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 21157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 21167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 21187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 21197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 21207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 21217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 21227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 10 /*virtual method*/; 21237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 21247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 21257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 21277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<OverrideAttr>()) { 21297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 21307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 21317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 21327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2133cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); 21347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 21357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 21367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 2137b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 2138b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 2139b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2140b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2141b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 2142b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 21435dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 2144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21455dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 21465dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 21475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 21485dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 21495dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 215021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 215121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 215221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2153b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2154b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 2155bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21566217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2157183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall || RetTy->getAs<ObjCObjectPointerType>())) { 215821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 215921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 216021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName(); 2161bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 21625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2164b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 2165b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 2166b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 2167b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 216831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2169cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 217031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 217131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 2172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context)); 217331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 2174b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2176b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2177b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context)); 2179b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2180b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 2181b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 2182b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2183f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2184f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 2185f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis Attr.getKind() == AttributeList::AT_dllexport; 2186f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 2187f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2188b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 21890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 21900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 21910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 2192a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2193803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 2194bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2195bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 2197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 2198e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara if (Attr.isInvalid()) 2199e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2200e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2201f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2202f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // FIXME: Try to deal with other __declspec attributes! 2203290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 2204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 220563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2206857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2207857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 2208857e918a8a40deb128840308a318bf623d68295fTed Kremenek HandleIBOutletCollection(D, Attr, S); break; 2209803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 2210ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 22116e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 2212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 2213bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 2214803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 22157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 22167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 2218af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 2219b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 2220bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 22217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 22227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2223bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 22247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 22257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 22267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 22277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 22283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 22299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 22303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 22317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 22327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 22337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 22347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 22357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 22367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 22377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 22387725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2239dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 2240dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 2241dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 2242dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek HandleOwnershipAttr (D, Attr, S); break; 22437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 22447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 22457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 224635cc9627340b15232139b3c43fcde5973e7fad30John Thompson case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2247b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2248b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 224931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 225031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2251b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2252b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2253b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 2254b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 22556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 22566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 22576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2258521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 2259521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian HandleInitPriorityAttr(D, Attr, S); break; 2260521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 22617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 22627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 22637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 22647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 22657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 22667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2267026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2268026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 22697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 227011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 22717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2272803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 2273803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 2274803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 22750db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 22760db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 22770db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 2278f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 22797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 22807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 22817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 22827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 22837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 22847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 22857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 22867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 22877725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2288bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 228905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 229005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 22917255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 22927255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner HandleNoInstrumentFunctionAttr(D, Attr, S); 22937255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 229404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 229504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 229604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 2297f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2298e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara HandleCallConvAttr(D, Attr, S); 229904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 2300803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 230182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 230282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 230382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 23047d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 23057d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 2306803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 2307803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2308803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2309803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2310803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2311803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 23129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 231311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 231411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola ProcessDeclAttribute(S, D, *l, *this); 231511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 231611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 231711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 231811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 231911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 232011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 232111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2322dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 232311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 2324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2325803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2327e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2328e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 23291eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 23307b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2331e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 2332e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2333e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2334e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 2335a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 2336b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (FD->getQualifier()) { 2337b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2338b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2339b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2340e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2341e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2342e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 2343a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 234416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 234516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 2346b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 2347b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 2348b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2349b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2350e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2351e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 2352e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2353e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 2354e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2355e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 23567b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2357c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 2358c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 2359c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2360c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 2361c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2362cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2363cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 2364cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2365c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 2366c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2367c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 2368c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 2369c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 2370c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 2371c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 2372c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 2373cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2374e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2375e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2376e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 23770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 23780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 23790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 23809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2381e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Handle #pragma weak 2382e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2383e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (ND->hasLinkage()) { 2384e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 2385e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W != WeakInfo()) { 23867b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn // Identifier referenced by #pragma weak before it was declared 23877b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn DeclApplyPragmaWeak(S, ND, W); 2388e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 2389e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2390e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2391e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2392e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 23930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 23940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 23959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2396bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 23980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 23990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 24000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 24010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 24020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 24039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 24060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 24079cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 24080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 240954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 241054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation 241154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings. 241254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// 241354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope 241454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack. 241554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallAction::ParsingDeclStackState Sema::PushParsingDeclaration() { 241654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth++; 24172f514480c448708ec382a684cf5e035d3a827ec8John McCall return (ParsingDeclStackState) DelayedDiagnostics.size(); 241854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 241954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 2420d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) { 242154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 242254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth--; 242354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 24242f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics.empty()) 242554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 242654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 242754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall unsigned SavedIndex = (unsigned) S; 24282f514480c448708ec382a684cf5e035d3a827ec8John McCall assert(SavedIndex <= DelayedDiagnostics.size() && 242954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall "saved index is out of bounds"); 243054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 243158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall unsigned E = DelayedDiagnostics.size(); 243258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 24332f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 24342f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 24352f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D) { 24362f514480c448708ec382a684cf5e035d3a827ec8John McCall // We really do want to start with 0 here. We get one push for a 24372f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 24382f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 24392f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 24402f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 24412f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 244258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = 0; I != E; ++I) { 24432f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics[I].Triggered) 24442f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 24452f514480c448708ec382a684cf5e035d3a827ec8John McCall 24462f514480c448708ec382a684cf5e035d3a827ec8John McCall switch (DelayedDiagnostics[I].Kind) { 24472f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 24482f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 24492f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 24502f514480c448708ec382a684cf5e035d3a827ec8John McCall 24512f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 24522f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 24532f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 245454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 245554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 245654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 245754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 245858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 245958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = SavedIndex; I != E; ++I) 246058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall DelayedDiagnostics[I].destroy(); 246158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 24622f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.set_size(SavedIndex); 24632f514480c448708ec382a684cf5e035d3a827ec8John McCall} 24642f514480c448708ec382a684cf5e035d3a827ec8John McCall 24652f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 24662f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 24672f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D->hasAttr<DeprecatedAttr>()) 24682f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 24692f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 24702f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 24712f514480c448708ec382a684cf5e035d3a827ec8John McCall} 24722f514480c448708ec382a684cf5e035d3a827ec8John McCall 24739c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 24742f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 24752f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 24762f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 24772f514480c448708ec382a684cf5e035d3a827ec8John McCall 24782f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 24792f514480c448708ec382a684cf5e035d3a827ec8John McCall Diag(DD.Loc, diag::warn_deprecated) 24802f514480c448708ec382a684cf5e035d3a827ec8John McCall << DD.DeprecationData.Decl->getDeclName(); 248154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 248254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 248354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCallvoid Sema::EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc) { 248454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 248554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (ParsingDeclDepth) { 24862f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D)); 248754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 248854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 248954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 249054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 249154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 249254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 249354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 249454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 249554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 2496