SemaDeclAttr.cpp revision 723df245307a530da5433dfb43accf187dc3e243
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 13007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) { 13107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d)) 13207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 13307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 13407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 13507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 137183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 138b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 141506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 142506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 145506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1536217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 155085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 156085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1576217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 158085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 162465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 163085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 164085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 165085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 166085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 167085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 168e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 169e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 170e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 171e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 178545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 179545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 180803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 181545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 190f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 191f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 192f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 193f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1979cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1999cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 2007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 2039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 2059ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 2069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 207ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 208a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 217545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 228803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 229fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 23008631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 232cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 23896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 23996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 24296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 243bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 24563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 24663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 247cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 24863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 24963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 25063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_ibaction) << Attr.getName(); 25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 25463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 25763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 25863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 26063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 262efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 263efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 26563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 266efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 26763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 26863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 26996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 27096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 271857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 272857e918a8a40deb128840308a318bf623d68295fTed Kremenek Sema &S) { 273857e918a8a40deb128840308a318bf623d68295fTed Kremenek 274857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 275a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 276857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 277857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 278857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 279857e918a8a40deb128840308a318bf623d68295fTed Kremenek 280857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 281857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 282857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 283857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName(); 284857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 285857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 2863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 2873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 2883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 2893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << VD->getType() << 0; 2903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 2913a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 2923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 2933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 2943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 2953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << PD->getType() << 1; 2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 2973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 2983a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 299a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 300a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 301a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian II = &S.Context.Idents.get("id"); 3023a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 303b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 304a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.getScopeForContext(d->getDeclContext()->getParent())); 305a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 309b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 310a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 313a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 314a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCClassType() && 315a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian !QT->isObjCObjectType()) { 316a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 317a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 318a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 319cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 320cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt QT)); 321857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 322857e918a8a40deb128840308a318bf623d68295fTed Kremenek 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 324bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 326d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 33207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 33307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 33407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 33507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 341eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 3457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 347ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 348ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 349fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 350fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 353bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 355bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 356eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 35830bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 360eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 361bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 362465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 36307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 36407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 36507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 36607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 36707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 36807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 36907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 37007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 37107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 372eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 373eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 374bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 375dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 376eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 377c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 378fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3797fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 380eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 382eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 384bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 385bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 386bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 38846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 38946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 390dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 391d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 392ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian else if (const RecordType *UT = T->getAsUnionType()) { 393ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 394ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 395ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 396ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 397ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian T = it->getType(); 398ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (T->isAnyPointerType() || T->isBlockPointerType()) { 399ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian NonNullArgs.push_back(I); 400ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian break; 401ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 402ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 403ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 404ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 40546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 406bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 407ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 40860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 40960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 41060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 41160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 41260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 4137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 41460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 415eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 4167fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 4177fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 4187fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 419dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 420cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 421cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 422eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 423eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 424dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 425dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 427dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 428dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 429dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 430dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 4312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 4322a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 438dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 440cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 4412a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 4422a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 443cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 447dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4492a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4642a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 4652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 4662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!isFunction(d) || !hasFunctionProto(d)) { 470dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << 0 /*function*/; 472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 47507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 47607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 47707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 47807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::StringRef Module = AL.getParameterName()->getName(); 481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 482dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 483dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 484dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::SmallVector<unsigned, 10> OwnershipArgs; 487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 4882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 4892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 4917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 498dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 50807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 50907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 51007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 51107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 51207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 51307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 51407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 51507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 51607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 518cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 519cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek QualType T = getFunctionOrMethodArgType(d, x); 522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 525cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 5357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 537dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 539dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 542dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 5472a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 5482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 552cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 553cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i = d->specific_attr_begin<OwnershipAttr>(), 554cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt e = d->specific_attr_end<OwnershipAttr>(); 555cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 556cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 557cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 558cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 560cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 561cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 562dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 564dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 565dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 572cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 573cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 574cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 575cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 577cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 578cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 580dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 581dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 58211e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic bool isStaticVarOrStaticFunciton(Decl *D) { 58311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (VarDecl *VD = dyn_cast<VarDecl>(D)) 584d931b086984257de68868a64a235c2b4b34003fbJohn McCall return VD->getStorageClass() == SC_Static; 58511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 586d931b086984257de68868a64a235c2b4b34003fbJohn McCall return FD->getStorageClass() == SC_Static; 58711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 58811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 58911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 59011e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 59111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 59211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 59311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 59411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 59511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 59611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 59711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 59811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 59911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 60011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 60111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 60211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 60311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 60411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 60511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 6077a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl const DeclContext *Ctx = d->getDeclContext()->getRedeclContext(); 6087a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 6097a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 6107a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl dyn_cast<NamedDecl>(d)->getNameAsString(); 6117a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 61211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 61511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 61611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 61711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 61811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 61911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 62011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 62111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 62211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 62311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 62411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 62511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (!isStaticVarOrStaticFunciton(d)) { 63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static) << 63411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola dyn_cast<NamedDecl>(d)->getNameAsString(); 63511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 63611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 63711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 63811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 63911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 64011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 64111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 64211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 6437a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Str == 0 || Str->isWide()) { 64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 654f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 655f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 65711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 65911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 66011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 661803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 663545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 667bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6687a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 671bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 673fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 678f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) { 679f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 680f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 681f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 682f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 684bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 685f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 686f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 689dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr, 690dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar Sema &S) { 691dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 692dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (Attr.getNumArgs() != 0) { 693dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 694dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 695dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 696dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 697dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (!isa<FunctionDecl>(d)) { 698dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 699dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar << Attr.getName() << 0 /*function*/; 700dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 701dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 702dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 703dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); 704dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 705dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 707af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 708dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 709af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 7103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 711af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 712af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 7135bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 714c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 7155bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 716dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar << Attr.getName() << 0 /*function*/; 7175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 7185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 720cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 721af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 722af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 72376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 724dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 72576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 72676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 72776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 72876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 7291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7302cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 7322cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 733cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 7342cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 7352cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 736fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 737fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 7382cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 73976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 74076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 74134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 74234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 74334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman if (Attr.getNumArgs() != 0) { 74434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 74534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 74634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman } 74734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 74834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context)); 74934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 75034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 751a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 752a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 753722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 754722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context)); 755722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 756722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 757722109c1b7718d3e8aab075ce65007b372822199Eric Christopher << Attr.getName() << 12 /* variable */; 758a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 759a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 760a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 761a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 762722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 763722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context)); 764722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 765722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 766722109c1b7718d3e8aab075ce65007b372822199Eric Christopher << Attr.getName() << 12 /* variable */; 767a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 768a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 769b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 770b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ 771b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek assert(Attr.isInvalid() == false); 772b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context)); 773b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 774b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 775b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 776b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek Sema &S) { 777b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 778b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 779b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 780b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 781545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 782e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 783b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 785b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 78619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 78719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 7883ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 7893ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 790e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 791e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 792b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 793b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek << Attr.getName() << 0 /*function*/; 794b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 79519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 797b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 798b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 80135cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 80235cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 80335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Sema &S) { 80435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 80535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 80635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 807f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 808f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 809f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 810f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 811f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 81235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 81335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 81435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 81535cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 81635cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 81735cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 81835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 81935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 82035cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 82135cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 82235cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 82335cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 82435cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 82535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 82635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 82701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<RecordDecl>(d)) { 82835cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 82935cc9627340b15232139b3c43fcde5973e7fad30John Thompson << Attr.getName() << 9 /*class*/; 83035cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 83135cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 83235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 83335cc9627340b15232139b3c43fcde5973e7fad30John Thompson if (d->getAttr<VecReturnAttr>()) { 83435cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 83535cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 83635cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 83735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 83801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson RecordDecl *record = cast<RecordDecl>(d); 83901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 84001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 84101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 84201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 84301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 84401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 84501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 84601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 84701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 84801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 84901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 85001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 851f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 852f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 85301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 85401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 85501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 85601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 85701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 85801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 85901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 860cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 86135cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 86235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 863bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 864bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 86604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall << Attr.getName() << 8 /*function, method, or parameter*/; 867bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 869bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 871bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 87273798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 87373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 87473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 8753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 87673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 87773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 878bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 879aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 880aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall !isa<TypeDecl>(d)) { 881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8825dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 88373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 88473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 88773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 88873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 889b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 890b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 891b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 892b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 893b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 894b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 895bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 896b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 897186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 898b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 899b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 900b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 901b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 902b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 904b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 905b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 907cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 908b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 909b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 9103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 9123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 913fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 914fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 9153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 916bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 9173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 9193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 9207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 9213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 922ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 923ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 9263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 9293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 931c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 932fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 937f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 938f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 9393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 9403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 9433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 944fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 945fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 9463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 947bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 9483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 9503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 9517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 9523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 953ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 954ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 955fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 9573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 9603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 961bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9626782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 963fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9645dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 968f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 969f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 9703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 9713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 972803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 974c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian int noArgs = Attr.getNumArgs(); 975c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (noArgs > 1) { 976c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian S.Diag(Attr.getLoc(), 977c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian diag::err_attribute_wrong_number_arguments) << "0 or 1"; 978c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 979c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 980c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 981c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian StringLiteral *SE; 982c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (noArgs == 1) { 9837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 984c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE = dyn_cast<StringLiteral>(ArgExpr); 985c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 986c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian S.Diag(ArgExpr->getLocStart(), 987c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian diag::err_attribute_not_string) << "deprecated"; 988c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 989c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 9906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 991c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 992c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE = StringLiteral::CreateEmpty(S.Context, 1); 993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 994c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, 995c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE->getString())); 9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 998bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 999bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 1000c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian int noArgs = Attr.getNumArgs(); 1001c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (noArgs > 1) { 1002f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Diag(Attr.getLoc(), 1003f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1004bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1005bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1006c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 1007c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian StringLiteral *SE; 1008c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (noArgs == 1) { 10097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1010c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE = dyn_cast<StringLiteral>(ArgExpr); 1011c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1012c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian S.Diag(ArgExpr->getLocStart(), 1013c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1014c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1015c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1016c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1017c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian else 1018c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE = StringLiteral::CreateEmpty(S.Context, 1); 1019c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, 1020c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE->getString())); 1021bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1022bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1023803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1025545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 10263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 10276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1029bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 10316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 10326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1033bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 1035fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 10363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 10376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1040c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 1041cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1043c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1044cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1045c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1046cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1047c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1048cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 1049c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 1050cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 10516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 105208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 10536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1055bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 10576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10590db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 10600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 10610db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 10620db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10630db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 10640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10660db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 10670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 10680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 10690db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 10700db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 10730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 10740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 10750db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 1076fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 10772b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1078fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1079fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 10800db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1081fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1082fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 10836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1084fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1085fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1086fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1087fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1089fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1090fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 1092f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1093f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 10942b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1095f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1096f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1097f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1098f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1099f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1100f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1101f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1102f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1103cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1104f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1105f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 11069eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1107bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1108fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 11093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 11109eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11119eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1112bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11139eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 11143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11159eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11169eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1117bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1118cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 111992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 11209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 11219eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1122fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 11233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 11249eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1127cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 11289eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 11299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 1130770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1131770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1132770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1133fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1134fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 1135770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1137bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1138770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 1139770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 11407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1141770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1142ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1143ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1144fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1146770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1147770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1148770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 1149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1150770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 1151fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1152fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1153770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1154770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1155770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1156770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1157770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 1158770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 11597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1160770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1161ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1162ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1165770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1166770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1167770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1168bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1169770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 1170770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1171770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1172fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1173fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1174770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1176770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1177770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1178770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1179183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1180897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 1181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1182897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1183897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1184897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1185897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1186bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1187897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 11883bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1189770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 11933bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 11952f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 11962f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 1197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 11992f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 12002f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 12012f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1202daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1204f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 12052f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 12063bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 12073bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 12082f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 12092f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1210ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 12112f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1212ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 12132f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 12142f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1215770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1216fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1217ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 1218770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1219770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1221f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1222770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1223770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1224026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1225026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 1226026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 1227026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1228026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1229026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1230026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1231f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1232026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12335dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1234026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1235026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1237f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1238f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1239f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1240f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1241f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1242f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1243f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1244f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1245f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1246f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1247f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1248f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1249cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1250026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1251026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1252026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 12536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1254545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 12553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1259f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 126011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (isStaticVarOrStaticFunciton(D)) { 1261f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 1262f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 1263f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1264f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1265f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 12666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 12676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 12686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12695dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 12706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 12716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1272bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1273cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12766e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 12776e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 12786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 12796e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 1281bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 12826e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 12836e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 12846e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 12856e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 12866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 12876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 128806a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis isDef = FD->hasBody(); 1289d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1290d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 12911c90f4dc686ab872013544664c797604a309c563Mike Stump return; 12925f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1293c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian // Don't issue the warning for darwin as target; yet, ignore the attribute. 12943be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1295c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian !isa<ObjCInterfaceDecl>(D)) 1296c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12973be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian << Attr.getName() << 2 /*variable and function*/; 12983be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian return; 12996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 13006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 13016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 13026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 1303bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 13046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 13056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 13066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 13076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 13086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1309cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 13106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 13116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 13126f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 13136f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 13146f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 13156f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 13162b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13176f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 13186f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 13196f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 13206f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 13216f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 13227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 13236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1324ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1325ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 13266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 13276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 13286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 13296f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 13306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 13316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1332cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1333cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 13346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 13356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 13366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 1337026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 133817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 133917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 134017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 134117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 134217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 134317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 134417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 134517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 13467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1347797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 134817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1349797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 135017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 135117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 13521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1353797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1354bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1355a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1356a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1357a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1358797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1359797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 13601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1361a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1362a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1363a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1364a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1365a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1366a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 1367f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1368f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 136917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 137017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1374545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 13753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 13766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1378bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1379cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 13806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1382232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1383232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1384232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 13853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1386232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1387232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1389cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1390232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1391232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1392232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1393232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1394232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 13953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1396232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1397232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1398bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1399cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1400232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1401232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1402f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1403bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1404f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1405f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1406f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1407bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1408f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1409f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1410f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1411f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1413f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1414bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1415f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1416f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1417f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1418f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1419bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1420f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1421c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 1422f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1423f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1424f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 1425f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 1426f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 1427f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1428f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1429f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1431f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1432f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 1433f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1434f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 1435f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1436f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1437f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1438f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1439f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 1440f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1441f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 1442f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1443f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1444f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 144689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 144789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 144889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 144989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 14501c23e91ef66688d20868b6bab3b5589a119eb603John McCall if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1451f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 145289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 145389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 145489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 145589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1458223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 1459f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1460f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1461bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1462bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 14655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 14665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 14675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 14685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 14695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 14705b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 14715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 14725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 147307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 147407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 147507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 147607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 147707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 14785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 147907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 14805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 14817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 14825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 1483ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1484ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 14855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 14875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 14885b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 14915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 14925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 14935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 14945b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1495bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14965b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1497bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 149807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 149907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 150007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 150107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 150207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 150307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 150407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 150507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 150607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 15075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 15085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 15115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 15125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 15135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 15146217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 15155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 15165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1517bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 15185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 15195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 15225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 15235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 15245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 15256217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 15265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 15275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1528bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 15295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 15305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1532bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 153307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 153407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 15355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 15365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 15372b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 15382b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 15392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 15402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 15412b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 15423c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 15432b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 15442b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 15452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 15462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 15472b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 15482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 15492b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 15502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 15512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 15522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 15532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 15542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 15552b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 15562b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 15572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 15582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 15592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 15602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 15612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 15622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 15632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1564bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1565bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 15663c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 15673c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 15682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 15692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 15702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1571521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 1572521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1573521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1574521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Sema &S) { 1575521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 1576521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1577521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1578521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1579521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1580b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1581b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1582b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1583b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1584b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1585b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian QualType T = dyn_cast<VarDecl>(d)->getType(); 1586b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 1587b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 1588b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 1589b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1590b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1591b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1592b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1593b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1594521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 1595521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1596521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1597521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1598521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 15997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 1600b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1601521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 1602521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1603521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1604521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1605521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 1606521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1607521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1608521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 16099f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 1610521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 1611521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1612521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 1613521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1614521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1615521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1616f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 1617f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 1618521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 1619521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1621bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1622803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1624545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1625fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 16263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 16276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1630545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 16313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 16326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1635620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1636fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 16386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 164107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 164207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 164307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 164407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 16456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 16466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 164701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 16486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 16502b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 16512b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 16522b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 16532b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 16542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 16553c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 16563c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 16573c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 16583c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 16592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1660fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 166101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 16626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 16667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 1667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1668ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1669ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1670fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 16713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 16726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1676fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 16773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 16786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 16826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1683bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16844a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 16854a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 168607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 168707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 168807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 16894a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 16904a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 16914a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 16924a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 16931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 16953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1698085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1699fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1700fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1701085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1702085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 17032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1704390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1705390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1706803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1707390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1708fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1709fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 17126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 17136217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1714390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1716fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 17176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 17217a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 1722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1723ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1724ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1725fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 17263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 17316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 17323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 17336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 17346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1735803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 17366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 17413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 17422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 17436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1744fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1745fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 17466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 17496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 17513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 17526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1755cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1756cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 17572b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 17586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 17596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 17610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 17626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1763545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 17643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 17656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 17690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1770bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 17710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 17720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 17730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 17740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 17750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 17760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1777fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 17785dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 17796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1783bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 17840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 17850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 17860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 17870c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 178817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 178917945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 17900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 17910c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 17920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 17930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1794bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 17950c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 17960c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 179790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1798bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 179990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 180090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 18010c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 18020c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1803bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 18040c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 18050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 18060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 18070c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 18080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 18090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 18100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 18110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1812bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 18130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1814bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 18150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 18160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 18170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1818bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 18190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 18200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1821bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1822bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1823bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1825cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 18276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 18296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1830545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 18313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18347a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1835797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1836bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 18386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1840797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 18416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1843f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 1844f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 18456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 18466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 18486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1849545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 18503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1853bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1854bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1855bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1856bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 18576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1858545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 1859cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 18604ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 18614ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 18624ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 18637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 18644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 18654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 18664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 18674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 18684ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 1869cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 18706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1873cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 187449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 18754ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 18764ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 18774ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 187849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 187949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1880396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 18814ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 18824ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 1883396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1884396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1885396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 1886cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1887cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 1888cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1889cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1890cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 1891cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 1892cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1893cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 18946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1895fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1896bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1898fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1899bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1900bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1901bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 19020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1903fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1904fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1905fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1906fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1907fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 19083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1909fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1910fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1911fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 19140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1915fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1917210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 191801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 1919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1920fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1921210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 1922210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 1923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1925fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 192673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1927210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 1928fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 192973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 193073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 193173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 193273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 193373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 193473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 193573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 193673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 193773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 193873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 193973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 194073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 194173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 194273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 194373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 194473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1946fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1947fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1949210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 19500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1951210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 19520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1953fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1955210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 19560b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1963fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1966fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1967fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 197073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1971183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 197273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 197373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 19742ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 197573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 197673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 197773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 197873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 197973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 198073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 198173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 198273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 198373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1984390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1985390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1986390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1987390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1988f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1989f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 19933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1994fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1995fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 19963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 199973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 200073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 200173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 200273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 20040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 200973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 201073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 201173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 201273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 20140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2017fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 20200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2021fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 20220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2023fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2025fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2026fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2027fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 20280b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2029fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2030aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2031aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2032aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2033aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2034fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2035aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2036aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2037aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2038aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2039fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 204073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 204173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 204273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2043f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2044f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2045f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2046f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2047f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2048f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2049f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2050f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2051f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 205273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 205573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 205673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2057fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2059fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2060ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 2061ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2062a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2063ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2065fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 20660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 20671feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2068d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 2069d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 2070d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2071d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2072d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2073e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 20745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 2075d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 20765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 2077d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2078d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2079bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2081d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2082d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 20831feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 20845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 20855bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 20865bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20875bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 20885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2089bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2090c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 20915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 20925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 20935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 20945bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2095bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2096cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 20975bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 20985bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 20997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 21007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner Sema &S) { 21017255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 21027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (Attr.getNumArgs() != 0) { 21037255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 21047255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 21057255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 21067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 21077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (!isa<FunctionDecl>(d)) { 21087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 21097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner << Attr.getName() << 0 /*function*/; 21107255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 21117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 21127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2113f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2114f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 21157255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 21167255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2117ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2118ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2119ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2120ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2121ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2122ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2123ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2124ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2125ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2126ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2127ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 12 /*variable*/; 2128ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2129ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2130ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2131ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2132ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2133ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2134ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2135ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2136ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2137ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2138ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2139ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2140ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2141ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2142ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2143ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2144ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2145ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) { 2146ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2147ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 2 /*variable and function*/; 2148ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2149ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2150ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2151ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2152ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2153ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2154ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2155ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2156ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2157ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2158ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2159ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2160ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2161ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2162ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2163ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2164ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2165ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2166ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2167ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 0 /*function*/; 2168ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 21712c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne FunctionDecl *FD = cast<FunctionDecl>(d); 21722c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2173723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 21742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 21752c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 21762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 21772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 21782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 21792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 21802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 21812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 21822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 21832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 21842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 21852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2188ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2196ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2198ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2202ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 0 /*function*/; 2203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2208ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2211ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2214ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2216ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2217ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2218ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2219ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2220ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2221ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2222ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 12 /*variable*/; 2223ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2224ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2225ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2226ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2227ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2228ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2229ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2230ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2231ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2232cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 223326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 223426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 223526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 223626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 223726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2239c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 2240c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 224126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 22425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 224326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 224426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2245bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22460130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2247cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2248c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2249c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2251cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 225226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 225326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 2254e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnarastatic void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2255e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2256e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2257e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara assert(Attr.isInvalid() == false); 2258e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2259e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara switch (Attr.getKind()) { 2260e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 2261cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 2262e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2263e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 2264cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 2265e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2266f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2267cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 226804633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 2269e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 2270cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 2271e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 227252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 227352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context)); 227452fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 2275e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 2276e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 2277e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2278e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 2279e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 2280e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2281ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2282ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 2283ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 228455d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2285ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2286ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 228755d3aaf9a537888734762170823daf750ea9036dEli Friedman 2288ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 2289ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 22905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 2291ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2292ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 229355d3aaf9a537888734762170823daf750ea9036dEli Friedman 22947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *NumParamsExpr = Attr.getArg(0); 229555d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 2296ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2297ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 229855d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 229955d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 230055d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 230155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 230255d3aaf9a537888734762170823daf750ea9036dEli Friedman 2303264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 2304264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 230555d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 230655d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 230755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 230855d3aaf9a537888734762170823daf750ea9036dEli Friedman 2309348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 2310264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2311264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 231255d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 231355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 231455d3aaf9a537888734762170823daf750ea9036dEli Friedman 2315cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, 2316cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NumParams.getZExtValue())); 2317ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 2318ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 23197b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){ 23207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 23217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 23227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 23237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 23247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "1 or 2"; 23257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 23267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 23287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (!isFunctionOrMethod(d)) { 23297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 23307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << Attr.getName() << 0 /*function*/; 23317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 23327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 23347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 23357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 23367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 23377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 23387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 23397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 23417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 23427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 23447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 23457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 23467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 23477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 23487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 23497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 23507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 23527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 23537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 23567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 23577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 23587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 23597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 23607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 23617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 23627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 23637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 2364bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2365bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // check the attribute arguments. 2366bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Attr.getNumArgs() != 0) { 2367bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2368bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 2369bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2370bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2371bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isa<CXXRecordDecl>(d) 2372bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { 2373bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), 2374bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 2375bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt : diag::warn_attribute_wrong_decl_type) 2376bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt << Attr.getName() << 7 /*virtual method or class*/; 2377bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 2378bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 23797725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 23807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 23817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 23827725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<FinalAttr>()) { 23837725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final"; 23847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 23857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 2386bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2387cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context)); 2388bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 2389bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 23900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 23917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt// C++0x member checking attributes 23927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 23937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 23947725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) { 23957725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 23967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 23977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 23987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 23997725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24007725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXRecordDecl>(d)) { 24017725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 24027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 24037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 24047725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 9 /*class*/; 24057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24067725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24077725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24087725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<BaseCheckAttr>()) { 24097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check"; 24107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2413cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context)); 24147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 24157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24167725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) { 24177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 24187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24217725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24227725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<RecordDecl>(d->getDeclContext())) { 24237725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 24247725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 24257725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 24267725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 24277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 11 /*member*/; 24287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 24327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<HidingAttr>()) { 24347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding"; 24357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24367725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24377725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2438cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context)); 24397725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 24407725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24417725e67639fa2fe74f8775b7ed884a076ffdbffcSean Huntstatic void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) { 24427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (Attr.getNumArgs() != 0) { 24437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) { 24487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: It's not the type that's the problem 24497725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), 24507725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 24517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt : diag::warn_attribute_wrong_decl_type) 24527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt << Attr.getName() << 10 /*virtual method*/; 24537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24547725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24557725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24567725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt // FIXME: Conform to C++0x redeclaration rules. 24577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt if (d->getAttr<OverrideAttr>()) { 24597725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override"; 24607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt return; 24617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt } 24627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 2463cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context)); 24647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt} 24657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt 24667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt//===----------------------------------------------------------------------===// 2467b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 2468b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 2469b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2470b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 2471b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 2472b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 24735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 2474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24755dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 24765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 24775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 24785dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 24795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 248021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 248121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 248221531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName() << 3 /* function or method */; 2483b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2484b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 2485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 2487183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall || RetTy->getAs<ObjCObjectPointerType>())) { 248821531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek SourceLocation L = Attr.getLoc(); 248921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 249021531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek << SourceRange(L, L) << Attr.getName(); 2491bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 24925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 2493bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2494b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 2495b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 2496b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 2497b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 249831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2499f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), 2500f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 250131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 250231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 2503f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), 2504f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 250531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 2506b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2507f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), 2508f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2509b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2510b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2511f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), 2512f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2513b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2514b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 2515b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 2516b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2517f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2518f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 2519f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis Attr.getKind() == AttributeList::AT_dllexport; 2520f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 2521f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2522b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 25230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 25240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 25250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 2526a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 2527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 2528bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 2529bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 2530bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 2531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 2532e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara if (Attr.isInvalid()) 2533e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2534e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2535f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 2536f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis // FIXME: Try to deal with other __declspec attributes! 2537290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 2538803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 253963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2540857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2541857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 2542857e918a8a40deb128840308a318bf623d68295fTed Kremenek HandleIBOutletCollection(D, Attr, S); break; 2543803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 2544ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 25456e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 25464211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 25474211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 2548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 2549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 2550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 25517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 25527725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 2554af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 2555b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 2556bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 25577725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 25587725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break; 2559bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 25607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 2561a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break; 2562ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break; 25637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 25647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 25657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 2566ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break; 25673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 25689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 25693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 25707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break; 25717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 25727725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2573ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; 25747725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 25757725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break; 2576ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break; 25777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 25787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne HandleLaunchBoundsAttr(D, Attr, S); 25797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 25807725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 25817725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 258234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break; 2583a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break; 25847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2585dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 2586dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 2587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 2588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek HandleOwnershipAttr (D, Attr, S); break; 2589dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break; 25907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 25917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 25927725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break; 2593ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break; 259435cc9627340b15232139b3c43fcde5973e7fad30John Thompson case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2595b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2596b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 259731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 259831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2599b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2600b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2601b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 2602b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 26036f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 26046f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 26056f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2606521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 2607521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian HandleInitPriorityAttr(D, Attr, S); break; 2608521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 26097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 26107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 26117725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 26127725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 26137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 26147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2615026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2616026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 26177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 261811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 26197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2620803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 2621803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 2622803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 26230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 26240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 26250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 2626f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 26277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 26287725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 26297725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 26307725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 26317725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 26327725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 26337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 26347725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 26357725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2636bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 263705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 263805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 26397255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 26407255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner HandleNoInstrumentFunctionAttr(D, Attr, S); 26417255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 264204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 264304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 264404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 2645f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 264652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2647e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara HandleCallConvAttr(D, Attr, S); 264804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 2649803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 265082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 265182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 265282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 26537d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 26547d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 2655803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 2656803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2657803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2658803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2659803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2660803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 2661f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 2662f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher const AttributeList *AttrList) { 266311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 266411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola ProcessDeclAttribute(S, D, *l, *this); 266511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 266611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 266711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 266811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 266911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 267011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 267111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2672dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 267311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 2674803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2676803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2677e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2678e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 26791eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 26807b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2681e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 2682e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2683e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2684e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 2685a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 2686b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (FD->getQualifier()) { 2687b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2688b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2689b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2690e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2691e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2692e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 2693a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 269416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 269516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 2696b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 2697b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 2698b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2699b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2700e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2701e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 2702e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2703e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 2704e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2705e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 27067b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2707c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 2708c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 2709c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2710c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 2711c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2712cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2713cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 2714cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2715c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 2716c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2717c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 2718c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 2719c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 2720c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 2721c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 2722c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 2723cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2724e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2725e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2726e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 27270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 27280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 27290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 27309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 2731d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 2732d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 2733d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (!WeakUndeclaredIdentifiers.empty()) { 2734d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2735d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (IdentifierInfo *Id = ND->getIdentifier()) { 2736d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 2737d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall = WeakUndeclaredIdentifiers.find(Id); 2738d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 2739d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakInfo W = I->second; 2740d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall DeclApplyPragmaWeak(S, ND, W); 2741d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakUndeclaredIdentifiers[Id] = W; 2742d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 2743e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2744e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2745e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2746e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 27470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 27480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 27499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2750bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 27520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 27530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 27540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 27550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 27560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 27579cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 2758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 27600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 27619cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 27620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 276354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 276454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation 276554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings. 276654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// 276754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope 276854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack. 2769f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() { 277054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth++; 27712f514480c448708ec382a684cf5e035d3a827ec8John McCall return (ParsingDeclStackState) DelayedDiagnostics.size(); 277254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 277354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 2774d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) { 277554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 277654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth--; 277754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 27782f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics.empty()) 277954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 278054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 278154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall unsigned SavedIndex = (unsigned) S; 27822f514480c448708ec382a684cf5e035d3a827ec8John McCall assert(SavedIndex <= DelayedDiagnostics.size() && 278354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall "saved index is out of bounds"); 278454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 278558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall unsigned E = DelayedDiagnostics.size(); 278658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 27872f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 27882f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 27892f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D) { 27902f514480c448708ec382a684cf5e035d3a827ec8John McCall // We really do want to start with 0 here. We get one push for a 27912f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 27922f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 27932f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 27942f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 27952f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 279658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = 0; I != E; ++I) { 27972f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics[I].Triggered) 27982f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 27992f514480c448708ec382a684cf5e035d3a827ec8John McCall 28002f514480c448708ec382a684cf5e035d3a827ec8John McCall switch (DelayedDiagnostics[I].Kind) { 28012f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 28022f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 28032f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 28042f514480c448708ec382a684cf5e035d3a827ec8John McCall 28052f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 28062f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 28072f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 280854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 280954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 281054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 281154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 281258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 281358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = SavedIndex; I != E; ++I) 281458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall DelayedDiagnostics[I].destroy(); 281558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 28162f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.set_size(SavedIndex); 28172f514480c448708ec382a684cf5e035d3a827ec8John McCall} 28182f514480c448708ec382a684cf5e035d3a827ec8John McCall 28192f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 28202f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 28212f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D->hasAttr<DeprecatedAttr>()) 28222f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 28232f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 28242f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 28252f514480c448708ec382a684cf5e035d3a827ec8John McCall} 28262f514480c448708ec382a684cf5e035d3a827ec8John McCall 28279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 28282f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 28292f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 28302f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 28312f514480c448708ec382a684cf5e035d3a827ec8John McCall 28322f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 2833ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 2834c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 2835ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 2836ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 2837c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 2838c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 2839ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 284054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 284154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 2842ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, 2843c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SourceLocation Loc) { 284454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 284554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (ParsingDeclDepth) { 2846c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D, 2847c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Message)); 284854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 284954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 285054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 285154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 285254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 285354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 2854ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 2855c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 2856c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 2857c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 2858c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 285954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 2860