SemaDeclAttr.cpp revision f315fa81eef1977b3457fd7a7d4639e060fe7278
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 81711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 82711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 83711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic bool hasDeclarator(const Decl *d) { 84711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 85711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefDecl>(d); 86711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 87711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 91a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 9372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 95d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 96d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 97d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 983568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 100d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 101d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 102d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 103a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 10489951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 106d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 107d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 10889951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1103568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 111a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 11289951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 11372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 114d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 115d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 116bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 120a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 126a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 127d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 131db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 132d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1353568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1363568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 13707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) { 13807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d)) 13907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 14007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 14107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 14207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 144183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 145b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 148506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 149506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 152506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1606217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 161085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 162085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 163085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1646217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 165085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 166085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 168085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 169465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 170085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 171085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 172085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 173085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 174085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 175e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 176e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 177e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 178e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 185545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 186545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 188545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 197f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 198f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 199f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 200f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 2019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 2029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 2039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 2069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 2077a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 2109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 2119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 2129ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 2139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 214ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 215a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 222803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 224545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 228bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 230cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 235803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 23708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 239cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 24596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 24696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 24996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 25263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 25363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 254cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 25563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 25663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 25763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 2584ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 25963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 26063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 26163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 26263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 26363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 26463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 26563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 26663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 26763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 26863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 269efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 270efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 271cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 27263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 273efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 27463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 2754ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 27696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 27796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 278857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 279857e918a8a40deb128840308a318bf623d68295fTed Kremenek Sema &S) { 280857e918a8a40deb128840308a318bf623d68295fTed Kremenek 281857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 282a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 283857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 284857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 285857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 286857e918a8a40deb128840308a318bf623d68295fTed Kremenek 287857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 288857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 289857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 2904ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 291857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 292857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 2933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 2943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 2953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 2963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << VD->getType() << 0; 2973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 2983a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 2993a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 3003a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 3013a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 3023a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << PD->getType() << 1; 3033a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 3043a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 3053a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 306a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 307a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 308a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian II = &S.Context.Idents.get("id"); 3093a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 310b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 311a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.getScopeForContext(d->getDeclContext()->getParent())); 312a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 313a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 314a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 315a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 316b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 317a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 318a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 319a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 320a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 321a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCClassType() && 322a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian !QT->isObjCObjectType()) { 323a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 324a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 325a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 326cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 327cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt QT)); 328857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 329857e918a8a40deb128840308a318bf623d68295fTed Kremenek 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 333d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 334fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3355dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 338bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 33907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 34007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 34107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 34207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 348eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 3527a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 353eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 354ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 355ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 362bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 363eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 364fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 36530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 366eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 369465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 37007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 37107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 37207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 37307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 37407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 37507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 37607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 37707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 37807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 380eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 381de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType(); 382dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 384c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 385fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 387eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 389eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 390eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 391bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 393bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3947fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 39546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 396de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType(); 397dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 398d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 399ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian else if (const RecordType *UT = T->getAsUnionType()) { 400ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 401ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 402ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 403ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 404ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian T = it->getType(); 405ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (T->isAnyPointerType() || T->isBlockPointerType()) { 406ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian NonNullArgs.push_back(I); 407ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian break; 408ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 409ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 410ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 411ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 41246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 414ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 41560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 41660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 41760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 41860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 41960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 4207fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 42160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 422eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 4237fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 4247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 4257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 426dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 427cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 428cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 429eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 430eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 431dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 432dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 433dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 434dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 435dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 436dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 437dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 4382a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 4392a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 442dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 443dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 444dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 445dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 447cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 4482a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 4492a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 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_holds: 457cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 458dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 459dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4622a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 464cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 467dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 468dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 469dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4712a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 4722a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 4732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 475dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 476dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!isFunction(d) || !hasFunctionProto(d)) { 477dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName() 478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << 0 /*function*/; 479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 48207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 48307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 48407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 48507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::StringRef Module = AL.getParameterName()->getName(); 488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 490dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 491dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 492dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 493dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::SmallVector<unsigned, 10> OwnershipArgs; 494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 4952a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 4962a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 497dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 4987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 502dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 503dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 504dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 505dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 512dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 51507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 51607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 51707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 51807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 51907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 52007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 52107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 52207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 52307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 525cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 526cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek QualType T = getFunctionOrMethodArgType(d, x); 529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 535dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 536dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 537dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 538dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 539cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 540dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 541dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 5427a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 543dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 545dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 552dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 5542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 5552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 556dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 557dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 558dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 560cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i = d->specific_attr_begin<OwnershipAttr>(), 561cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt e = d->specific_attr_end<OwnershipAttr>(); 562cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 563cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 564cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 565cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 566cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 567cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 568cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 574dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 575dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 580cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 582cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 583dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 584cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 585cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 586cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 587dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 588dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 589332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 590332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 591332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 592332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 593332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 594332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 595332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 596332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 597332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 598332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 599332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 600332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 601332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 602332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 603332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 604332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 605332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 60611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 60711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 60811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 60911e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 61011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 61111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 61211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 61311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 61411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 61511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 616332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) { 617332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 618332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall << Attr.getName() << 2 /*variables and functions*/; 619332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 620332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 621332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 622332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall NamedDecl *nd = cast<NamedDecl>(d); 623332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 62411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 62511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 6347a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl const DeclContext *Ctx = d->getDeclContext()->getRedeclContext(); 6357a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 6367a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 6387a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 63911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 64011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 64111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 64211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 64311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 65411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 65511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 65611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 65711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 65811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 659332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 660332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 66111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 66211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 6697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 67311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Str == 0 || Str->isWide()) { 67411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 67511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 67611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 67711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 67911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 680f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 681f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 684cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 687803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 689545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 6903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 693bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 699fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 7003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 704f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) { 705f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 706f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 707f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 708f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 710bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 711f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 712f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 715dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr, 716dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar Sema &S) { 717dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 718dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (Attr.getNumArgs() != 0) { 719dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 720dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 721dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 722dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 723dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (!isa<FunctionDecl>(d)) { 724dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 725dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar << Attr.getName() << 0 /*function*/; 726dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 727dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 728dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 729dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); 730dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 731dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 733af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 734dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 735af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 7363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 737af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 738af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 7395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 740c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 7415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 742dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar << Attr.getName() << 0 /*function*/; 7435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 7445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 746cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 747af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 748af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 74976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 750dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 75176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 75276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 75376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 75476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7562cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 7582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 759cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 7602cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 7612cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 762fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 763fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 7642cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 76576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 76676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 76734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 76834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 76934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman if (Attr.getNumArgs() != 0) { 77034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 77134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 77234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman } 77334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 77434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context)); 77534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 77634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 777a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 778a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 779722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 780722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context)); 781722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 782722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 783722109c1b7718d3e8aab075ce65007b372822199Eric Christopher << Attr.getName() << 12 /* variable */; 784a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 785a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 786a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 787a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 788722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 789722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context)); 790722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 791722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 792722109c1b7718d3e8aab075ce65007b372822199Eric Christopher << Attr.getName() << 12 /* variable */; 793a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 794a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 795711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) { 796711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 797711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 798711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 799711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 800711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 801711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 802711c52bb20d0c69063b52a99826fb7d2835501f1John McCall << attr.getName() << 0 /*function*/; 803711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 804711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 805711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 806711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context)); 807711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 808711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 809711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 810711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 0) { 811711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 812711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 813711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 814711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 815711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 816711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 817b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 818b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 819b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 820b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek Sema &S) { 821b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 822b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 823b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 824b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 825545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 826e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 827b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 829b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 83019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 83119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 8323ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 8333ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 834e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 835e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 836b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 837b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek << Attr.getName() << 0 /*function*/; 838b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 83919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 841b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 842b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 8436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 84535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 84635cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 84735cc9627340b15232139b3c43fcde5973e7fad30John Thompson Sema &S) { 84835cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 84935cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 85035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 851f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 852f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 853f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 854f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 855f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 85635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 85735cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 85835cc9627340b15232139b3c43fcde5973e7fad30John Thompson 85935cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 86035cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 86135cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 86235cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 86335cc9627340b15232139b3c43fcde5973e7fad30John Thompson 86435cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 86535cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 86635cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 86735cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 86835cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 86935cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 87035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 87101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<RecordDecl>(d)) { 87235cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 87335cc9627340b15232139b3c43fcde5973e7fad30John Thompson << Attr.getName() << 9 /*class*/; 87435cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 87535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 87635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 87735cc9627340b15232139b3c43fcde5973e7fad30John Thompson if (d->getAttr<VecReturnAttr>()) { 87835cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 87935cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 88035cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 88135cc9627340b15232139b3c43fcde5973e7fad30John Thompson 88201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson RecordDecl *record = cast<RecordDecl>(d); 88301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 88401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 88501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 88601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 88701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 88801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 88901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 89001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 89101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 89201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 89301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 89401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 895f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 896f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 89701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 89801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 89901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 90001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 90101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 90201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 90301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 904cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 90535cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 90635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 909bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 91004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall << Attr.getName() << 8 /*function, method, or parameter*/; 911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 912bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 913bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 914bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 915bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 91673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 91773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 91873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 9193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 92073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 92173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 922bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 923aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 924aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall !isa<TypeDecl>(d)) { 925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 92773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 92873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 93173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 93273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 933b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 934b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 935b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 936b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 937b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 938b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 939bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 940b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 941186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 942b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 943b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 944b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 945b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 946b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 948b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 949b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 950bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 952b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 953b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 9543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 9563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 957fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 958fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 9593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 960bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 9613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 9633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 9647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 9653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 966ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 967ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 968fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 9703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 9733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 974bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 975c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 976fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 981f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 982f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 9833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 9843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 9873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 988fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 989fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 9903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 9943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 9957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 9963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 997ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 998ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 999fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 10013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 10023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 10043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1005bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10066782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 1007fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 10103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1012f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 1013f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 10143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 10153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1016803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1018c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian int noArgs = Attr.getNumArgs(); 1019c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (noArgs > 1) { 1020c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian S.Diag(Attr.getLoc(), 1021c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1022c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1023c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1024c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 1025c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian StringLiteral *SE; 1026c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (noArgs == 1) { 10277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1028c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE = dyn_cast<StringLiteral>(ArgExpr); 1029c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1030c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian S.Diag(ArgExpr->getLocStart(), 1031c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian diag::err_attribute_not_string) << "deprecated"; 1032c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1033c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1035c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 1036c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE = StringLiteral::CreateEmpty(S.Context, 1); 1037bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1038c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, 1039c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian SE->getString())); 10406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1042bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1043bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 1044c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian int noArgs = Attr.getNumArgs(); 1045c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (noArgs > 1) { 1046f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Diag(Attr.getLoc(), 1047f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher diag::err_attribute_wrong_number_arguments) << "0 or 1"; 1048bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1049bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1050c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 1051c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian StringLiteral *SE; 1052c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (noArgs == 1) { 10537a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1054c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE = dyn_cast<StringLiteral>(ArgExpr); 1055c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1056c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian S.Diag(ArgExpr->getLocStart(), 1057c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1058c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1059c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1060c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1061c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian else 1062c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE = StringLiteral::CreateEmpty(S.Context, 1); 1063c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, 1064c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian SE->getString())); 1065bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1066bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1067803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1069545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 10703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 10716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1073bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10747a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1077bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 1079fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 10803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1083bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1084c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 1085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1087c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1089c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1091c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 1093c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 1094cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 10956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 109608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 10976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1100cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 11040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 11050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 11060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 11070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 11080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 11110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 11120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 11130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 11140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1115bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1116cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 11170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 11180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 11190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 1120fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 11212b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1122fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1123fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 11240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1125fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1126fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 11276217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1128fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1129fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1130fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1131fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1132cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1133fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1134fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 1136f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1137f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 11382b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1139f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1140f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1141f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1142f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1143f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1144f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1145f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1146f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1147cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1148f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1149f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 11509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1152fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 11533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 11549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11559eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 11583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11599eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11609eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1161bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1162cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 116392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 11649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 11659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 11673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 11689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 11699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1171cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 11729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 11739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 1174770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1176770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1177fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 1178fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 1179770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1180bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1181bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1182770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 1183770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 11847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1185770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1186ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1187ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1188fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1190770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 1193bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 1195fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1197770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1198770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1199770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1200770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1201770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 1202770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 12037a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1204770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1205ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1206ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1209770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1210770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1211770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1212bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1213770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 1214770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1215770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1216fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1217fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1218770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1219770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1220770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1221770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1222770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1223183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1224897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 1225bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1226897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1227897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1228897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1229897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1231897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 12323bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1233770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1235770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1236770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 12373bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1238770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 12392f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 12402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 1241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 12432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 12442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 12452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1246daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1248f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 12492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 12503bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 12513bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 12522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 12532f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1254ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 12552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1256ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 12572f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 12582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1259770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1261ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 1262770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1263770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1264f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1265f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1266770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1267770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1268026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1269026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 1270026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 1271026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1272026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1273026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1274026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1275f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1276026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12775dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1278026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1279026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1280bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1281f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1282f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1283f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1284f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1285f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1286f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1287f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1288f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1289f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1290f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1291f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1292f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1293cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1294026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1295026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1296332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) { 12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1298332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (attr.getNumArgs() != 0) { 1299332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 13006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13026e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1303332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) { 1304332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1305332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall << attr.getName() << 2 /*variables and functions*/; 1306f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1307f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1308f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 1309332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall NamedDecl *nd = cast<NamedDecl>(d); 1310332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1311332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 1312332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 1313332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::err_attribute_weak_static); 13146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 13156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1317332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context)); 13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 13216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 13226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 13236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 13246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 1325bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 13266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 13276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 13286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 13296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 13306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 13316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 133206a54a38be5054c910ffc92db60edab23f9ea105Argyrios Kyrtzidis isDef = FD->hasBody(); 1333d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 1334d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 13351c90f4dc686ab872013544664c797604a309c563Mike Stump return; 13365f8f8571c52dbf12fdefb15d2fedbcccb212c15cFariborz Jahanian } else if (!(S.LangOpts.ObjCNonFragileABI && isa<ObjCInterfaceDecl>(D))) { 1337c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian // Don't issue the warning for darwin as target; yet, ignore the attribute. 13383be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian if (S.Context.Target.getTriple().getOS() != llvm::Triple::Darwin || 1339c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian !isa<ObjCInterfaceDecl>(D)) 1340c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 13413be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian << Attr.getName() << 2 /*variable and function*/; 13423be17941f1edff4843692066f9d33d438a517612Fariborz Jahanian return; 13436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 13446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 13456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 13466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 1347bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 13486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 13496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 13506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 13516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 13526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1353cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 13546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 13556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 13566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 13576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 13586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 13596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 13602b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 13626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 13636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 13646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 13656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 13667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 13676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1368ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1369ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 13706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 13716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 13726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 13736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 13746f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 13756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1376cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1377cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 13786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 13796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 13806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 1381026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 138217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 138317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 138417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 138517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 138617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 138717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 138817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 138917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 13907a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1391797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 139217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1393797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 139417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 139517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1397797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1398bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1399a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1400a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1401a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1402797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1403797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 14041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1405a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1406a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1407a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1408a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1409a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1410a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 1411f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 141317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 141417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 14156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1418545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 14193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 14206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1423cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 14246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 14256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1426232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1427232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1428232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 14293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1430232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1431232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1433cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1434232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1435232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1436232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1437232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1438232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 14393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1440232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1441232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1443cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1444232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1445232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1446f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1447bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1448f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1449f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1450f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1451bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1452f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1453f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1454f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1455f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1457f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1458bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1459f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1460f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1461f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1462f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1464f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1465c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 1466f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1467f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1468f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 1469f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 1470f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 1471f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1472f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1473f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1474bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1475f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1476f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 1477f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1478f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 1479f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1480f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1481f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1482f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1483f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 1484f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1485f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 1486f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1487f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1488f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 149089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 149189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 149289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 149389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1494b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 1495b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 1496f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 149789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 149889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 149989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 150089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1501bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1502cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1503223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 1504f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1505f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1506bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1507bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 15095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 15105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 15115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 15125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 15135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 15145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 15165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 15175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 151807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 151907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 152007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 152107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 152207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 15235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 152407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 15255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 15267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 15275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 1528ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1529ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 15305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 15325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 15335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1534bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 15365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 15375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 15385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 15395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1540bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 154307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 154407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 154507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 154607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 154707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 154807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 154907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 155007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 155107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 15525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 15535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 15565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 15575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 15585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 15596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 15605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 15615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1562bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 15635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 15645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1565bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 15675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 15685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 15695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 15706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 15715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 15725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1573bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 15745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 15755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1576bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1577bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 157807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 157907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 15805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 15815b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 15822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 15832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 15842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 15852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 15862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 15873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 15882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 15892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 15902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 15912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 15922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 15932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 15942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 15952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 15962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 15972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 15982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 15992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 16002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 16012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 16022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 16032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 16042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 16052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 16062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "zcmn_err") 16072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 16082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1609bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1610bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 16113c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 16123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 16132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 16142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 16152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1616521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 1617521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1618521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1619521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Sema &S) { 1620521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 1621521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1622521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1623521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1624521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1625b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1626b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1627b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1628b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1629b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1630b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian QualType T = dyn_cast<VarDecl>(d)->getType(); 1631b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 1632b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 1633b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 1634b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1635b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1636b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1637b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1638b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1639521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 1640521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1641521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1642521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1643521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 16447a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 1645b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1646521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 1647521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1648521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1649521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1650521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 1651521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1652521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1653521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 16549f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 1655521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 1656521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1657521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 1658521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1659521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1660521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1661f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 1662f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 1663521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 1664521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1666bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1669545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1670fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 16713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 16726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1675545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 16763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 16776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1680620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16825dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 16836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 16856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 168607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 168707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 168807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 168907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 16906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 16916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 169201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 16936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 16952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 16962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 16982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 16992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 17003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 17013c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 17023c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 17033c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 17042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1705fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 170601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 17076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 17117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 1712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1713ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1714ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 17163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 17176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1721fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 17223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1728bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17294a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 17304a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 173107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 173207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 173307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 17344a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 17354a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 17364a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 17374a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 17381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 17403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 17416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17422b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1744fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1745fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1746085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1747085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 17482b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1749390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1750390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1751803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1752390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1753fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1754fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 17556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1756bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 17576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 17586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1759390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1760fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1761fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 17626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 17667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 1767803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1768ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1769ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1770fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 17713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 17726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 17766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 17773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 17786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 17796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1780803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 17816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 17863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 17872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 17886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1789fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1790fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 17916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 17946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1795fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 17963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 17976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1800cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1801cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 18022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 18036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 18046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18050b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 18060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1808545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 18093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 18106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 18140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1815bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 18160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 18170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 18180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 18190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 18200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 18210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1822fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 18235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 18290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 18300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 18310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 18320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 183317945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 183417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 18350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 18360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 18370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 18380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1839bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 18400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 18410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 184290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1843bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 184490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 184590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 18460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 18470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1848bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 18490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 18500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 18510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 18520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 18530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 18540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 18550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 18560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 18580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 18600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 18610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 18620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 18640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 18650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1866bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1867bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1868bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 18696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1870cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 18726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 18746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1875545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 18763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1880797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1881bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 18836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 18846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1885797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 18866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1888f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 1889f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18924ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 18936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1894545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 18953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1898bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1899bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1900bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1901bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 19026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1903545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 1904cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 19054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 19064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 19074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 19087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 19094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 19104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 19114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 19124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 19134ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 1914cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 19156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1918cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 191949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 19204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 19214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 19224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 192349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 192449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1925396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 19264ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 19274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 1928396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1929396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1930396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 1931cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 1932cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 1933cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1934cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 1935cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 1936cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 1937cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 1938cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 19396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1940fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1941bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1943fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1944bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1945bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1946bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 19470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1949fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1952fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 19533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1955fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1956fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 19590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1962210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 196301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 1964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1966210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 1967210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 1968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 197173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1972210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 1973fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 197473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 197573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 197673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 197773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 197873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 197973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 198073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 198173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 198273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 198373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 198473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 198573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 198673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 198773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 198873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 198973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1994210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 19950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1996210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 19970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2000210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 20010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 2002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2004fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 2007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2011fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 2013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 201573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2016183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 201773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 201873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 20192ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 202073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 202173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 202273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 202373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 202473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 202573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 202673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 202773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 202873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2029390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2030390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2031390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2032390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2033f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2034f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2035fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2036fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2037fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 20383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2039fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2040fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 20413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2042fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2043fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 204473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 204573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 204673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 204773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 20490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 205473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 205573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 205673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 205773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 20590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 20650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2066fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 20670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 20690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2071fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 20730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2075aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2076aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2077aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2078aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2079fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2080aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2081aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2082aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2083aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 208573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 208673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 208773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2088f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2089f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2090f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2091f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2092f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2093f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2094f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2095f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2096f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 209773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2098fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2099fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 210073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 210173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2105ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 2106ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2107a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2108ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2110fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 21110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 21121feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2113d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 2114d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 2115d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2116d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2117d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2118e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 21195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 2120d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 21215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 2122d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2123d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2125cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2126d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2127d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 21281feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 21295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 21305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 21315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 21325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 21335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2135c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 21365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 21375dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 21385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 21395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2141cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 21425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 21435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 21447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 21457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner Sema &S) { 21467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 21477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (Attr.getNumArgs() != 0) { 21487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 21497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 21507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 21517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 21527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (!isa<FunctionDecl>(d)) { 21537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 21547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner << Attr.getName() << 0 /*function*/; 21557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 21567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 21577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2158f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2159f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 21607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 21617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2162ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2163ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2164ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2165ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2166ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2167ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2168ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2171ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2172ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 12 /*variable*/; 2173ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2174ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2175ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2176ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2177ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2178ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2179ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2180ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2181ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2182ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2183ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2184ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2185ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2188ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) { 2191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 2 /*variable and function*/; 2193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2196ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2198ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2202ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2208ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2211ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 0 /*function*/; 2213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2214ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 22162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne FunctionDecl *FD = cast<FunctionDecl>(d); 22172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2218723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 22192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 22202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 22212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 22222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 22232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 22242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 22252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 22262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 22272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 22282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 22292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 22302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2231ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2232ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2233ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2234ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2235ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2236ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2237ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2238ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2239ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2240ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2241ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2242ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2243ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2244ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2245ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2246ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2247ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 0 /*function*/; 2248ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2249ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2250ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2251ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2252ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2253ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2254ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2255ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2256ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2257ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2258ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2259ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2260ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2261ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2263ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2265ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2267ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne << Attr.getName() << 12 /*variable*/; 2268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2269ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2270ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2272ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2273ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2277cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 227826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 227926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 228026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 228126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 228226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2284c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 2285c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 228626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 22875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 228826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 228926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22910130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2292cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2293c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2294c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2296cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 229726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 229826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 2299711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) { 2300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 2301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2302711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // Diagnostic is emitted elsewhere: here we store the (valid) attr 2303e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 2305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckCallingConvAttr(attr, CC)) 2306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2307e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 2309711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall << attr.getName() << 0 /*function*/; 2311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 2315e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 2316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context)); 2317e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2318e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 2319711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context)); 2320e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2321f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context)); 232304633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 2324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 2325711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context)); 2326e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 232752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2328711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context)); 232952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 2330e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 2331e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 2332e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2333e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 2334e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 2335e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2336f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournestatic void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){ 2337f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne assert(Attr.isInvalid() == false); 2338f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context)); 2339f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 2340f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 2341711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2342711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2343711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2344711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2345711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 0) { 2346711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2347711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2348711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2349ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 235055d3aaf9a537888734762170823daf750ea9036dEli Friedman 2351711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // TODO: diagnose uses of these conventions on the wrong target. 2352711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 2353711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 2354711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 2355711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 2356711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 2357711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 2358711c52bb20d0c69063b52a99826fb7d2835501f1John McCall default: llvm_unreachable("unexpected attribute kind"); return true; 2359711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2360711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2361711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 2362711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 2363711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2364711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) { 2365711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 2366711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2367711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 2368711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckRegparmAttr(attr, numParams)) 2369711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2370711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2371711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 2372711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2373711c52bb20d0c69063b52a99826fb7d2835501f1John McCall << attr.getName() << 0 /*function*/; 2374ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2375ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 237655d3aaf9a537888734762170823daf750ea9036dEli Friedman 2377711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams)); 2378711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 2379711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2380711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 2381711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 2382711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) { 2383711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2384711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2385711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2386711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 1) { 2387711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2388711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2389711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2390711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2391711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2392711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Expr *NumParamsExpr = attr.getArg(0); 239355d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 2394ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2395711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 2396711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_argument_not_int) 239755d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 2398711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2399711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 240055d3aaf9a537888734762170823daf750ea9036dEli Friedman } 240155d3aaf9a537888734762170823daf750ea9036dEli Friedman 2402711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (Context.Target.getRegParmMax() == 0) { 2403711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 240455d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 2405711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 240755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 240855d3aaf9a537888734762170823daf750ea9036dEli Friedman 2409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 2410711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (numParams > Context.Target.getRegParmMax()) { 2411711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2413711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2414711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 241555d3aaf9a537888734762170823daf750ea9036dEli Friedman } 241655d3aaf9a537888734762170823daf750ea9036dEli Friedman 2417711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 2418ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 2419ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 24207b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){ 24217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 24227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 24237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 24247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 24257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "1 or 2"; 24267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 24277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 24297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (!isFunctionOrMethod(d)) { 24307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 24317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << Attr.getName() << 0 /*function*/; 24327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 24337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 24357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 24367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 24377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 24387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 24397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 24407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 24417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 24427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 24437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 24457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 24467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 24477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 24487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 24497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 24507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 24517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 24527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 24537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 24547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 24577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 24587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 24597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 24607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 24617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 24627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 24637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 24647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 24650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 2466b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 2467b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 2468b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2469c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 2470c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type); 2471c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2472c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 2473c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isPointerType() || isValidSubjectOfNSAttribute(S, type); 2474c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2475c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2476c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) { 2477c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall ParmVarDecl *param = dyn_cast<ParmVarDecl>(d); 2478c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 2479c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2480c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << 4 /*parameter*/; 2481c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2482c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2483c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2484c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 2485c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (attr.getKind() == AttributeList::AT_ns_consumed) { 2486c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 2487c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 2488c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 2489c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 2490c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 2491c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2492c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2493c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 2494c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 2495c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << cf; 2496c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2497c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2498c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2499c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 2500c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context)); 2501c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 2502c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context)); 2503c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2504c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2505c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr, 2506c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall Sema &S) { 2507c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!isa<ObjCMethodDecl>(d)) { 2508c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2509c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << 13 /*method*/; 2510c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2511c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2512c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2513c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context)); 2514c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2515c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2516c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr, 2517b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 2518b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2519c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 2520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2522c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 25235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2524c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 25255dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 252621531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2527c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() 2528c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << 3 /* function or method */; 2529b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2530b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 2531bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2532c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 2533c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 2534c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall switch (attr.getKind()) { 2535c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall default: llvm_unreachable("invalid ownership attribute"); return; 2536c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 2537c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 2538c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 2539c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 2540c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 2541c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 2542c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2543c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 2544c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 2545c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 2546c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 2547c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 2548c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2549c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2550c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 255121531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2552c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) 2553c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << attr.getName() << isa<ObjCMethodDecl>(d) << cf; 2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 25555dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 2556bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2557c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall switch (attr.getKind()) { 2558b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 2559b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 2560b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2561c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 2562c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(), 2563c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 2564c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 256531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2566c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(), 2567f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 256831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 256931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 2570c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(), 2571f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 257231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 2573b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2574c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(), 2575f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2576b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2577b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2578c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(), 2579f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2580b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2581b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 2582b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 2583b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2584f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2585f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 258611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_dllexport || 258711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_uuid; 258811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 258911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 259011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 259111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 259211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 259311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 259411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) { 259511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet if (S.LangOpts.Microsoft || S.LangOpts.Borland) { 259611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 259711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet if (Attr.getNumArgs() != 1) { 259811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 259911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 260011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet } 260111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 260211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2603d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (Str == 0 || Str->isWide()) { 2604d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2605d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 2606d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2607d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2608d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2609d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet llvm::StringRef StrRef = Str->getString(); 2610d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2611d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 2612d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 2613d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2614d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 2615d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 2616d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2617d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2618d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2619d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 2620d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2621d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2622d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2623d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2624d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 2625d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 2626f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson llvm::StringRef::iterator I = StrRef.begin(); 2627f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 2628f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 2629f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 2630f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 2631d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 2632d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 2633d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2634d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2635d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2636d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 2637d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2638d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2639d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2640d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 2641d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 264211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 264311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context, 264411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 2645d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 264611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 2647f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 2648f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2649b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 26500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 26510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 26520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 265360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D, 265460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S) { 265560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 265660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break; 265760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break; 265860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 265960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 266060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 266160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 266260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 2663e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 266460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessInheritableDeclAttr(Scope *scope, Decl *D, 266560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S) { 2666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 266763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2668857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2669857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 2670857e918a8a40deb128840308a318bf623d68295fTed Kremenek HandleIBOutletCollection(D, Attr, S); break; 2671803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 2672ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 26736e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 26744211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 26754211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 2676bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 2677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 2678803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 267960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 268060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 268160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 268260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 268360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 268460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 26857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 26867725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 2688af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 2689b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 2690bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 26917725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 2692bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 26937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 2694a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break; 2695ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break; 26967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 26977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 26987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 26993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 27009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 27013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 27027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 27037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2704ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; 27057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 27067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 27077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne HandleLaunchBoundsAttr(D, Attr, S); 27087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 27097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 27107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 271134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break; 2712a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break; 27137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2714dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 2715dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 2716dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 2717dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek HandleOwnershipAttr (D, Attr, S); break; 2718dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break; 27197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 27207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2721ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break; 272235cc9627340b15232139b3c43fcde5973e7fad30John Thompson case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2723b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2724b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 2725c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 2726c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumed: HandleNSConsumedAttr (D, Attr, S); break; 2727c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 2728c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall HandleNSConsumesSelfAttr(D, Attr, S); break; 2729c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2730c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 273131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 273231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2733b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2734b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2735b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 2736b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 27376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 27386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 27396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2740521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 2741521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian HandleInitPriorityAttr(D, Attr, S); break; 2742521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 27437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 27447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 27457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 27467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 27477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 27487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2749026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2750026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 27517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 275211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 27537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2754803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 2755803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 2756803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 27570db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 27580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 27590db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 27607725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 27617725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 27627725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 27637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 27647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 27657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 27667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 27677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 27687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 277005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 277105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 27727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 27737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner HandleNoInstrumentFunctionAttr(D, Attr, S); 27747255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 277504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 277604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 277704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 2778f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 277952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2780e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara HandleCallConvAttr(D, Attr, S); 278104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 2782f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 2783f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne HandleOpenCLKernelAttr(D, Attr, S); 2784f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 278511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 278611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet HandleUuidAttr(D, Attr, S); 278711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 2788803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 278982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 279082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 279182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 27927d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 27937d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 2794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 2795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2796803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 279860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 279960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 280060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 280160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 280260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessDeclAttribute(Scope *scope, Decl *D, 280360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S, 280460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 280560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 280660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 280760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 280860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 280960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 281060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 281160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 281260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 281360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessNonInheritableDeclAttr(scope, D, Attr, S); 281460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 281560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 281660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessInheritableDeclAttr(scope, D, Attr, S); 281760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 281860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 2819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 2821f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 282260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 282360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 282411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 282560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable); 282611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 282711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 282811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 282911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 283011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 283160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 283211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2833dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 283411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 2835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2836803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2837803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2838e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2839e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 28401eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 28417b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2842e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 2843e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2844e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2845e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 2846a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 2847b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (FD->getQualifier()) { 2848b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2849b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange()); 2850b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2851e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2852e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2853e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 2854a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 285516573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 285616573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 2857b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 2858b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 2859b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange()); 2860b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2861e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2862e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 2863e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2864e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 2865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 28677b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2868c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 2869c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 2870c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2871c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 2872c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2873cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2874cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 2875cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2876c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 2877c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2878c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 2879c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 2880c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 2881c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 2882c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 2883c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 2884cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2886e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2887e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 28880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 28890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 28900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 289160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 289260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 2893d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 2894d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 289560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && !WeakUndeclaredIdentifiers.empty()) { 2896d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 2897d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (IdentifierInfo *Id = ND->getIdentifier()) { 2898d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 2899d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall = WeakUndeclaredIdentifiers.find(Id); 2900d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 2901d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakInfo W = I->second; 2902d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall DeclApplyPragmaWeak(S, ND, W); 2903d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakUndeclaredIdentifiers[Id] = W; 2904d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 2905e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2906e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2907e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2908e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 29090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 29107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 291160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 2912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 29140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 29150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 29160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 29170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 29180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 291960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 2920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 29220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 292360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 29240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 292554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 292654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// PushParsingDeclaration - Enter a new "scope" of deprecation 292754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// warnings. 292854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// 292954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// The state token we use is the start index of this scope 293054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall/// on the warning stack. 2931f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCallSema::ParsingDeclStackState Sema::PushParsingDeclaration() { 293254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth++; 29332f514480c448708ec382a684cf5e035d3a827ec8John McCall return (ParsingDeclStackState) DelayedDiagnostics.size(); 293454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 293554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 2936d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) { 293754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack"); 293854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclDepth--; 293954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 29402f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics.empty()) 294154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 294254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 294354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall unsigned SavedIndex = (unsigned) S; 29442f514480c448708ec382a684cf5e035d3a827ec8John McCall assert(SavedIndex <= DelayedDiagnostics.size() && 294554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall "saved index is out of bounds"); 294654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 294758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall unsigned E = DelayedDiagnostics.size(); 294858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 29492f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 29502f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 29512f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D) { 29522f514480c448708ec382a684cf5e035d3a827ec8John McCall // We really do want to start with 0 here. We get one push for a 29532f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 29542f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 29552f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 29562f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 29572f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 295858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = 0; I != E; ++I) { 29592f514480c448708ec382a684cf5e035d3a827ec8John McCall if (DelayedDiagnostics[I].Triggered) 29602f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 29612f514480c448708ec382a684cf5e035d3a827ec8John McCall 29622f514480c448708ec382a684cf5e035d3a827ec8John McCall switch (DelayedDiagnostics[I].Kind) { 29632f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 29642f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedDeprecationCheck(DelayedDiagnostics[I], D); 29652f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 29662f514480c448708ec382a684cf5e035d3a827ec8John McCall 29672f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 29682f514480c448708ec382a684cf5e035d3a827ec8John McCall HandleDelayedAccessCheck(DelayedDiagnostics[I], D); 29692f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 297054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 297154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 297254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 297354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 297458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 297558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall for (unsigned I = SavedIndex; I != E; ++I) 297658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall DelayedDiagnostics[I].destroy(); 297758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 29782f514480c448708ec382a684cf5e035d3a827ec8John McCall DelayedDiagnostics.set_size(SavedIndex); 29792f514480c448708ec382a684cf5e035d3a827ec8John McCall} 29802f514480c448708ec382a684cf5e035d3a827ec8John McCall 29812f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 29822f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 29832f514480c448708ec382a684cf5e035d3a827ec8John McCall if (D->hasAttr<DeprecatedAttr>()) 29842f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 29852f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 29862f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 29872f514480c448708ec382a684cf5e035d3a827ec8John McCall} 29882f514480c448708ec382a684cf5e035d3a827ec8John McCall 29899c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 29902f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 29912f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 29922f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 29932f514480c448708ec382a684cf5e035d3a827ec8John McCall 29942f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 2995ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 2996c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 2997ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 2998ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 2999c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 3000c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 3001ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 300254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 300354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3004ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, 30058e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 3006743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne bool UnknownObjCClass) { 300754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 300854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (ParsingDeclDepth) { 3009c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian DelayedDiagnostics.push_back(DelayedDiagnostic::makeDeprecation(Loc, D, 3010c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Message)); 301154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 301254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 301354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 301454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 301554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 301654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 3017ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 3018c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 3019c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 30208e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 3021743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 30228e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 30238e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else 30248e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 30258e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 302654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 3027