SemaDeclAttr.cpp revision def863192f83d8033e1833b48ae8119a65dfc7c8
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 27883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 28883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCallenum { 30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameterOrMethod, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassOrVirtualMethod, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVirtualMethod, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassMember, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableFunctionOrLabel 45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall}; 46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall 47e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 51a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic const FunctionType *getFunctionType(const Decl *d, 52a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek if (const ValueDecl *decl = dyn_cast<ValueDecl>(d)) 556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const FieldDecl *decl = dyn_cast<FieldDecl>(d)) 576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 58a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek else if (const TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 62bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 646217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 65755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 68183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 713568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 74d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 75a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunction(const Decl *d) { 77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return getFunctionType(d, false) != NULL; 78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethod(const Decl *d) { 84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek return isFunction(d)|| isa<ObjCMethodDecl>(d); 85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 87620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 90a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodOrBlock(const Decl *d) { 91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 98d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 103711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic bool hasDeclarator(const Decl *d) { 104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return isa<DeclaratorDecl>(d) || isa<BlockDecl>(d) || isa<TypedefDecl>(d); 106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 107711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 108d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 109d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 110620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 111a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool hasFunctionProto(const Decl *d) { 112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 11372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 115d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(d)); 116d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 117d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1193568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 123a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic unsigned getFunctionOrMethodNumArgs(const Decl *d) { 12489951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 12572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 126d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 127d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 12889951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 1293568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1303568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 131a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodArgType(const Decl *d, unsigned Idx) { 13289951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 13372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 134d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 135d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1383568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1393568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 140a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic QualType getFunctionOrMethodResultType(const Decl *d) { 1415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 146a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenekstatic bool isFunctionOrMethodVariadic(const Decl *d) { 147d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 14872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 150d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 151db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 152d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 15707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruthstatic bool isInstanceMethod(const Decl *d) { 15807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(d)) 15907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 16007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 164183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 165b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 168506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 169506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 179085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1806217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 187bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 189465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 195e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 196e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 197e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 198e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 2003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 2013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 2023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 2049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, Sema &S) { 205545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 206545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 207803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 208545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 2129cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 2139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 2149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 2159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 2169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 217f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 218f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 219f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 220f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); 2219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 2229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 2239cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 2249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 2269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 2277a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 2309cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 2319cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 2329ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 2339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 234ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 235a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 236bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2379cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 2389cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 2396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 242803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 244545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 248bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 250cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 255803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 256fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 25708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 259cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) { 26596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 26696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 26896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 26996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 270bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 27263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 27363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 274cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 27563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 27663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 27763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 2784ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 27963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 28063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 28163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenekstatic void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) { 28263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 28363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (Attr.getNumArgs() > 0) { 28463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 28563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 28663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 28763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 28863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 289efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 290efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) { 291cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 29263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 293efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 29463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 2954ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 29696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 29796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 298857e918a8a40deb128840308a318bf623d68295fTed Kremenekstatic void HandleIBOutletCollection(Decl *d, const AttributeList &Attr, 299857e918a8a40deb128840308a318bf623d68295fTed Kremenek Sema &S) { 300857e918a8a40deb128840308a318bf623d68295fTed Kremenek 301857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 302a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 303857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 304857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 305857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 306857e918a8a40deb128840308a318bf623d68295fTed Kremenek 307857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 308857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 309857e918a8a40deb128840308a318bf623d68295fTed Kremenek if (!(isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))) { 3104ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 311857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 312857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 3133a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ValueDecl *VD = dyn_cast<ValueDecl>(d)) 3143a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 3153a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 3163a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << VD->getType() << 0; 3173a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 3183a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 3193a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d)) 3203a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 3213a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 3223a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << PD->getType() << 1; 3233a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 3243a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 3253a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 326a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 327a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 328a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian II = &S.Context.Idents.get("id"); 3293a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 330b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 331a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.getScopeForContext(d->getDeclContext()->getParent())); 332a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 333a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 334a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 335a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 336b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 337a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 338a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 339a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 340a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 341a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCClassType() && 342a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian !QT->isObjCObjectType()) { 343a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 344a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 345a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 346cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 347cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt QT)); 348857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 349857e918a8a40deb128840308a318bf623d68295fTed Kremenek 350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 351bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 353d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 354fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 355883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 356eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 357eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 35907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 36007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 36107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 36207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 363eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 366bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 369bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 370bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 371eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 3727a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 373eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 374ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 375ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 376fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 377fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 378eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 380bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 381eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 382bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 384fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 38530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 386eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 387eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 389465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 39007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 39107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 39207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 39307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 39407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 39507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 39607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 39707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 39807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 399eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 400eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 401de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType(); 402dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 403eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 404c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 405fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 4067fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 407eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 408bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 409eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 410eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 412bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 4147fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 41546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 416de43632a5951abf3f357e2f79dcddda4dc6ec8ffDouglas Gregor QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType(); 417dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 418d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 419ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian else if (const RecordType *UT = T->getAsUnionType()) { 420ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 421ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 422ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 423ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 424ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian T = it->getType(); 425ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian if (T->isAnyPointerType() || T->isBlockPointerType()) { 426ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian NonNullArgs.push_back(I); 427ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian break; 428ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 429ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 430ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 431ff3a078d2a67db9ae6ff4cc0f799a209f85a4e91Fariborz Jahanian } 43246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 434ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 43560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 43660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 43760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 43860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 43960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 4407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 44160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 442eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 4437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 4447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 4457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 446dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 447cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 448cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 449eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 450eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 451dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenekstatic void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) { 452dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 453dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 454dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 455dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 456dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 457dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 4582a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 4592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 460dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 461dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 462dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 463dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 464dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 465dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 466dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 467cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 4682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 4692a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 470cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 471dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 472dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 473dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 474dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 477cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 478dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 479dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 480dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 481dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 484cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 485dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 486dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 487dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 488dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 489dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 4902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 4912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 4922a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 4932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 494dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 495dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 496dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!isFunction(d) || !hasFunctionProto(d)) { 497883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 498883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 499dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 500dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 501dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 50207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 50307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 50407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 50507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 506dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 507dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::StringRef Module = AL.getParameterName()->getName(); 508dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 509dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 510dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 511dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 512dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 513dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::SmallVector<unsigned, 10> OwnershipArgs; 514dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 5152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 5162a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 517dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 5187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 519dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 520dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 521dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 522dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 523dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 524dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 525dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 526dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 527dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 528dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 529dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 530dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 531dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 532dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 533dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 534dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 53507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 53607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 53707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 53807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 53907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 54007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 54107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 54207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 54307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 544dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 545cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 546cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek QualType T = getFunctionOrMethodArgType(d, x); 549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 550dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 551dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 552cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 553dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 554dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 555dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 556dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 557dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 558dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 559cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 560dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 561dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 5627a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 563dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 564dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 565dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 566dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 567dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 568dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 569dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 570dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 571dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 572dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 573dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 5742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 5752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 576dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 577dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 578dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 579cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 580cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i = d->specific_attr_begin<OwnershipAttr>(), 581cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt e = d->specific_attr_end<OwnershipAttr>(); 582cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 583cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 584cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 585cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 586cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 587cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 588cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 589dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 590dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 591dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 592dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 593dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 594dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 595dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 596dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 597dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 598dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 599cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 600cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 602cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 603dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 604cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 605cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 606cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 607dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 608dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 609332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 610332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 611332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 612332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 613332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 614332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 615332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 616332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 617332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 618332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 619332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 620332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 621332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 622332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 623332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 624332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 625332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 62611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 62711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 62811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 62911e8ce7380856abee188b237c2600272df2ed09dRafael Espindolastatic void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) { 63011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 63111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 63211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 63311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 63411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 63511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 636332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) { 637332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 638883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 639332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 640332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 641332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 642332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall NamedDecl *nd = cast<NamedDecl>(d); 643332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 64411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 64511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 64611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 64711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 64811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 64911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 65011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 65111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 65211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 65311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 6547a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl const DeclContext *Ctx = d->getDeclContext()->getRedeclContext(); 6557a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 6567a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 657332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 6587a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 65911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 66011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 66111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 66211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 66311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 66411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 66511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 66611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 66711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 66811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 66911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 67011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 67111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 67211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 67311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 67411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 67511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 67611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 67711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 67811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 679332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 680332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 68111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 68211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 68311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 68411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 68511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 68611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 68711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 68811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 6897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 69011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 69111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 69211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 69311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Str == 0 || Str->isWide()) { 69411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 69511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 69611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 69711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 69811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 69911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 700f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 701f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 70211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 70311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 70511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 70611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 707803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 709545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 7103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 713bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 719fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 7203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 7216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 723bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 724f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola if (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin) { 725f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 726f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 727f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 728f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 731f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 732f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 735dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbarstatic void HandleNakedAttr(Decl *d, const AttributeList &Attr, 736dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar Sema &S) { 737dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 738dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (Attr.getNumArgs() != 0) { 739dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 740dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 741dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 742dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 743dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar if (!isa<FunctionDecl>(d)) { 744dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 745883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 746dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 747dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 748dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 749dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar d->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); 750dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 751dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 753af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 754dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 755af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 7563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 757af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 758af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 7595bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 760c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 7615bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 762883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 7635bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 7645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 765bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 766cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 767af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 768af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 76976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynnstatic void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { 770dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 77176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn if (Attr.getNumArgs() != 0) { 77276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 77376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 77476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 7751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7762cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 7771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 7782cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 779cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 7802cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 7812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 782fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 783fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 7842cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 78576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 78676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 78734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohmanstatic void HandleMayAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 78834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 78934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman if (Attr.getNumArgs() != 0) { 79034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 79134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 79234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman } 79334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 79434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman d->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context)); 79534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 79634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 797a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleNoCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 798a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 799722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 800722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context)); 801722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 802722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 803883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 804a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 805a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 806a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopherstatic void HandleCommonAttr(Decl *d, const AttributeList &Attr, Sema &S) { 807a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher assert(Attr.isInvalid() == false); 808722109c1b7718d3e8aab075ce65007b372822199Eric Christopher if (isa<VarDecl>(d)) 809722109c1b7718d3e8aab075ce65007b372822199Eric Christopher d->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context)); 810722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 811722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 812883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 813a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 814a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 815711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleNoReturnAttr(Decl *d, const AttributeList &attr, Sema &S) { 816711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 817711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 818711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 819711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 820711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 821711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 822883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 823711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 824711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 825711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 826711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context)); 827711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 828711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 829711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 830711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 0) { 831711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 832711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 833711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 834711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 835711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 836711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 837b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 838b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 839b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 840b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek Sema &S) { 841b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 842b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 843b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 844b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 845545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 846e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 847b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 849b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 85019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 85119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 8523ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 8533ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 854e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 855e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 856b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 857883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 858b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 85919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 861b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 862b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 8636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 86535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 86635cc9627340b15232139b3c43fcde5973e7fad30John Thompsonstatic void HandleVecReturnAttr(Decl *d, const AttributeList &Attr, 86735cc9627340b15232139b3c43fcde5973e7fad30John Thompson Sema &S) { 86835cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 86935cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 87035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 871f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 872f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 873f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 874f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 875f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 87635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 87735cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 87835cc9627340b15232139b3c43fcde5973e7fad30John Thompson 87935cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 88035cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 88135cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 88235cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 88335cc9627340b15232139b3c43fcde5973e7fad30John Thompson 88435cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 88535cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 88635cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 88735cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 88835cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 88935cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 89035cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 89101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<RecordDecl>(d)) { 89235cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 893883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 89435cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 89535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 89635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 89735cc9627340b15232139b3c43fcde5973e7fad30John Thompson if (d->getAttr<VecReturnAttr>()) { 89835cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 89935cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 90035cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 90135cc9627340b15232139b3c43fcde5973e7fad30John Thompson 90201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson RecordDecl *record = cast<RecordDecl>(d); 90301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 90401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 90501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 90601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 90701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 90801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 90901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 91001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 91101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 91201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 91301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 91401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 915f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 916f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 91701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 91801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 91901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 92001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 92101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 92201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 92301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 924cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 92535cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 92635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 927bbd37c62e34db3f5a95c899723484a76c71d7757Sean Huntstatic void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { 928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { 929bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 930883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 931bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 932bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 933bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 93673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 93773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 93873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 9393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 94073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 94173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 942bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 943aec586056d8670c99ba7c4833be13e4eb123cddbJohn McCall if (!isa<VarDecl>(d) && !isa<ObjCIvarDecl>(d) && !isFunctionOrMethod(d) && 94457ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner !isa<TypeDecl>(d) && !isa<LabelDecl>(d)) { 945fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 946883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 94773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 94873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 949bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 95173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 95273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 953b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 954b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 955b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 956b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 957b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 958b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 959bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 960b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 961186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 962b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 963b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 964b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 965b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 966b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 967883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 968b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 969b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 970bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 971cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 972b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 973b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 9743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 976bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 977bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 9783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 9803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 9813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 9823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 9837a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 9843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 985ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 986ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 987fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 9883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 9893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 9923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 994c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 995fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 996883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 9973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 9983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 9993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1000f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 1001f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 10023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 10033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 10043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1006bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1007bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 10083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1009bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 10103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 10113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 10123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 10137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 10143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1015ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1016ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1017fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 10193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 10203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 10213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 10223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1023bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 10246782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 1025fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1026883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 10273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1030f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 1031f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 10323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 10333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1034803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1035951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1036951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1037bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1038c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1039c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1040951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1041c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 1042951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner llvm::StringRef Str; 1043951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1044951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1045c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1046951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1047951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner << "deprecated"; 1048c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1049c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1050951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 10516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1052bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1053951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str)); 10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1056bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1057951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1058951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1059bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1060bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1061bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1062951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1063c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 1064951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner llvm::StringRef Str; 1065951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1066951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1067c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1068951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), 1069c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1070c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1071c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1072951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 1073c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1074951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str)); 1075bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1076bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 10770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorstatic void HandleAvailabilityAttr(Decl *d, const AttributeList &Attr, 10780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Sema &S) { 10790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor IdentifierInfo *Platform = Attr.getParameterName(); 10800a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SourceLocation PlatformLoc = Attr.getParameterLoc(); 10810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 10820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor llvm::StringRef PlatformName 10830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 10840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (PlatformName.empty()) { 10850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 10860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << Platform; 10870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 10880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 10890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 10900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 10910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 10920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 10930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 10940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 10950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // Ensure that Introduced < Deprecated < Obsoleted (although not all 10960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 10970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Deprecated.isValid() && 10980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor !(Introduced.Version < Deprecated.Version)) { 10990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 11000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << PlatformName << Deprecated.Version.getAsString() 11010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 11020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 11030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 11040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 11050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Obsoleted.isValid() && 11060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor !(Introduced.Version < Obsoleted.Version)) { 11070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 11080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 11090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 11100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 11110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 11120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 11130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Deprecated.isValid() && Obsoleted.isValid() && 11140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor !(Deprecated.Version < Obsoleted.Version)) { 11150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 11160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 11170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << Deprecated.Version.getAsString(); 11180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 11190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 11200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 11210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor d->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context, 11220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Platform, 11230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Introduced.Version, 11240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Deprecated.Version, 11250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Obsoleted.Version)); 11260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 11270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1128803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1130545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 11313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11357a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 11376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 1140fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 11413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1144bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1145c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer llvm::StringRef TypeStr = Str->getString(); 1146cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1148c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1149cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1150c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1151cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1152c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1153cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 1154c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 1155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 115708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1161cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 11626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1164d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCallstatic void HandleObjCMethodFamilyAttr(Decl *decl, const AttributeList &attr, 1165d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall Sema &S) { 1166d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1167d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 1168d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall S.Diag(attr.getLoc(), diag::err_attribute_wrong_decl_type) 1169883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 1170d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1171d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1172d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1173d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (attr.getNumArgs() != 0 || !attr.getParameterName()) { 1174d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!attr.getParameterName() && attr.getNumArgs() == 1) { 1175d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall S.Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 1176d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 1177d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 1178d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1179d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1180d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall attr.setInvalid(); 1181d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1182d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1183d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1184d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall llvm::StringRef param = attr.getParameterName()->getName(); 1185d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 1186d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 1187d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 1188d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 1189d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 1190d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 1191d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 1192d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 1193d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 1194d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 1195d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1196d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 1197d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 1198d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 1199d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 1200d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 1201d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall S.Diag(attr.getParameterLoc(), diag::warn_unknown_method_family); 1202d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1203d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall decl->addAttr(new (S.Context) ObjCMethodFamilyAttr(attr.getLoc(), 1206d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall S.Context, family)); 1207d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 1208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 12090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 12100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 12110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 12120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 12140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 12170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 12180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 12190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 12200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1222cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 12230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 12240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 12250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 1226fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 12272b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1228fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1229fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 12300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 1231fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1232fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 12336217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1234fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1235fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1236fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1237fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1238cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1239fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1240fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 1242f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1243f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 12442b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1245f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1246f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1247f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1248f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1249f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1250f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1251f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1252f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1253cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1254f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1255f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 12569eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1258fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 12593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 12609eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 12619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1262bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 12643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 12669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1267bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1268cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 126992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 12709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 12719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1272fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 12733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 12749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 12759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1277cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 12789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 12799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 1280770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1281770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1282770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1283bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1284770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1285bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1286bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1287770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 1288770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 12897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1290770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1291ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1292ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1293fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1295770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1296770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1297770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 1298bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1299770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 1300fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1301fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1302770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1303770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1304770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1305770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1306770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 1307770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 13087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1309770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1310ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1311ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1312fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 13133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1314770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1315770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1316770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1318770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 1319770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1320770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1321fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1322fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1323770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1324770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1325770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1326770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1327770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 1328183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1329897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 1330bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1331897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1332897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1333897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1334897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1336897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 13373bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1338770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1339bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1340770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 1341770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 13423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 13442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 13452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 1346bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1347bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 13482f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 13492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 13502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1351daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 1352bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 1353f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 13542f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 13553bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 13563bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 13572f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 13582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1359ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 13602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1361883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 13622f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 13632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1364770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1365fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1366883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1367770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1368770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1369f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1370f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1371770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1372770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1373026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 1374026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 1375026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 1376026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1377026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1378026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1379026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1380f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1381026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1382883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 1383026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1384026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1385bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1386f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1387f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1388f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1389f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1390f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1391f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1392f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1393f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1394f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1395f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1396f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1397f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1398cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1399026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1400026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1401332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic void HandleWeakAttr(Decl *d, const AttributeList &attr, Sema &S) { 14026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1403332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (attr.getNumArgs() != 0) { 1404332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 14056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1408332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!isa<VarDecl>(d) && !isa<FunctionDecl>(d)) { 1409332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1410883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedVariableOrFunction; 1411f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1412f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1413f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 1414332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall NamedDecl *nd = cast<NamedDecl>(d); 1415332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1416332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 1417332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 1418332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(attr.getLoc(), diag::err_attribute_weak_static); 14196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 14206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1421bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1422332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->addAttr(::new (S.Context) WeakAttr(attr.getLoc(), S.Context)); 14236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 14246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 14266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 14276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 14286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 14296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 1430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 14326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 14336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 14340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 14350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 14360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 14370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 14380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 1439def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 1440def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor (S.Context.Target.getTriple().getOS() == llvm::Triple::Darwin && 1441def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor isa<ObjCInterfaceDecl>(D))) { 1442def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 1443def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 1444c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1445883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 14466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 14476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 14486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 14496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1450cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 14516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 14526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 14536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 14546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 14556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 14566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 14572b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 14586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 14596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 14606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 14616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 14626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 14637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 14646f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1465ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1466ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 14676f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 14686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 14696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 14706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 14716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 14726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1473cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1474cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 14756f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 14766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 14776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 1478026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 147917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 148017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 148117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 148217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 148317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 148417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 148517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 148617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 14877a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1488797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 148917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1490797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 149117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 149217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 14931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1494797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1495bb377edda2656752016a0bc01fe4f9f8b6f80e19Benjamin Kramer std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); 1496a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1497a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1498a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1499797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1500797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 15011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1502a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1503a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1504a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1505a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1506a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1507a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 1508f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1509f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 151017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 151117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 15126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1513803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 15146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1515545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 15163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 15176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1519bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1520cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 15216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1523232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1524232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1525232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 15263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1527232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1528232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1529bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1530cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 1531232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1532232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1533232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1534232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1535232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 15363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1537232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1538232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1539bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1540cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 1541232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1542232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1543f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1545f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1546f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1547f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1549f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1550f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1551f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1552f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1554f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1556f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1557f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1558f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1559f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1560bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1561f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 1562c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 1563f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 1564f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 1565f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 1566f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 1567f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 1568f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1569f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1570f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1571bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1572f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1573f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 1574f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1575f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 1576f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1577f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1578f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1579f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1580f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 1581f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 1582f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 1583f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 1584f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1585f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1586bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 158789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 158889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 158989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 159089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1591b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 1592b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 1593f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 159489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 159589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 159689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 159789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1598bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1599cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 1600223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 1601f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1602f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1603bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1605bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 16075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 16095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 16105b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 16115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1612883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 16135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 16145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 161507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 161607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 161707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 161807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 161907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 16205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 162107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 16225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 16237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 16245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 1625ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1626ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 16275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 16285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 16295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 16305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1631bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 16335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 16345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 16355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 16365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1637bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 164007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 164107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 164207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 164307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 164407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 164507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 164607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 164707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 164807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 16495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 16505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 16535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 16545b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 16555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 16566217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 16575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 16585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1659bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 16605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 16615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 16635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 16645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 16655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 16665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 16676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 16685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 16695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1670bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 16715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 16725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1673bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1674bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 167507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 167607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 16775b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 16785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 16792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 16802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 16812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 16822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 16832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 16843c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 16852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 16862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 16872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 16882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 16892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 16902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarstatic FormatAttrKind getFormatAttrKind(llvm::StringRef Format) { 16912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 16922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 16932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 16942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 16952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 16962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 16972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 16982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 16992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 17002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 17012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 17022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 1703cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "zcmn_err" || 1704cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "kprintf") // OpenBSD. 17052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 17062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1707bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 1708bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 17093c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 17103c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 17112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 17122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 17132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 1714521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 1715521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 1716521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanianstatic void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 1717521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Sema &S) { 1718521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 1719521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1720521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1721521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1722521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1723b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!isa<VarDecl>(d) || S.getCurFunctionOrMethodDecl()) { 1724b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1725b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1726b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1727b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1728b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian QualType T = dyn_cast<VarDecl>(d)->getType(); 1729b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 1730b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 1731b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 1732b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 1733b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 1734b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 1735b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 1736b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1737521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 1738521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1739521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1740521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1741521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 17427a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 1743b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 1744521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 1745521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 1746521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 1747521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1748521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 1749521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1750521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1751521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 17529f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 1753521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 1754521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 1755521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 1756521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 1757521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 1758521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 1759f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 1760f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 1761521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 1762521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1764bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1765803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 17666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1767545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1768fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 17693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 17706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1773545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 17743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 17756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1778620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1779fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1780883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 17816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 17836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 178407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 178507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 178607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth bool HasImplicitThisParam = isInstanceMethod(d); 178707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(d) + HasImplicitThisParam; 17886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 17896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 179001eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Format = Attr.getParameterName()->getName(); 17916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 17932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 17942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 17952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 17962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 17972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 17983c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 17993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 18003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 18013c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 18022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 1803fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 180401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 18056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 18097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 1810803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1811ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 1812ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1813fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 18156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1819fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 18203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 18216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 18256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18274a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 18284a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 182907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 183007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 183107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 18324a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 18334a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 18344a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 18354a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 18361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 18383568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 18396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18402b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 1841085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1843fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1844085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1845085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 18462b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 1847390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1848390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1850390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1851fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1852fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 18536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 18556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 18566217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1857390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1858fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 18606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 18647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 1865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1866ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 1867ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1868fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 18706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 18746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 18753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 18766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 18776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1878803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 18796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 18833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 18843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 18852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 18866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1887fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1888fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 18896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 18926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1893fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 18943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 18956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1898cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 1899cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 19002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 19016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 19026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 19040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 19056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1906545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 19073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 19120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1913bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 19140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 19150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 19160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 19170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 19180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 19190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1920fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1921883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 19226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 19270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 19280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 19290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 19300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 193117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 193217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 19330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 19340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 19350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 19360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1937bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 19380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 19390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 194090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 1941bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 194290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 194390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 19440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 19450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1946bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 19470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 19480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 19490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 19500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 19510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 19520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 19530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 19540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1955bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 19560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 19580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 19590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 19600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1961bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 19620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 19630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1964bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1965bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1966bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 19676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1968cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 19696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 19706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1973545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 19743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 19756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1978797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 1979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 19816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 19826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 1983797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 19846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1986f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 1987f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 19886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 19896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19904ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthstatic void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { 19916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1992545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 19933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 1997bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 1998bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 1999bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2001545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2002cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 20034ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 20044ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 20054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 20067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 20074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 20084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 20094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 20104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 20114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2012cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 20136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 20146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2015bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2016cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 201749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 20184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 20194ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 20204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 202149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 202249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 2023396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 20244ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 20254ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2026396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2027396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2028396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2029cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 2030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2031cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2032cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 2033cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2034cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2035cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 2036cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 20376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2038fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2039bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 2040bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2041fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2042bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2043bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2044bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 20450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 2046fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2047fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2049fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 2050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 20513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2055fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2056fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 20570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2059fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2060210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 206101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar llvm::StringRef Str = Attr.getParameterName()->getName(); 2062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2064210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2065210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2066fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2067fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 206973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2070210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2071fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 207273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 207373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 207473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 207573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 207673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 207773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 207873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 207973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 208073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 208173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 208273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 208373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 208473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 208573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 208673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 208773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2088fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2089fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 2090fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2091fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 2092210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 20930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 2094210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 20950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 2096fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2097fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2098210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 20990b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 2100fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2101fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 2105fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2106fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2107fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2109fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2110fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 2111fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 211373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2114183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 211573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 211673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 21172ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 211873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 211973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 212073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 212173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 212273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 212373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 212473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 212573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 212673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2127390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2128390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2129390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2130390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2131f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2132f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2133fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2134fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2135fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 21363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2137fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2138fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 21393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2140fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2141fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 214273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 214373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 214473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 214573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2146fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 21470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2148fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 21490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2150fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2151fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 215273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 215373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 215473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 215573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2156fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 21570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2158fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 21590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2160fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2161fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2162fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 21630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2164fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 21650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2166fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 21670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2168fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2169fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2170fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 21710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2172fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2173aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2174aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2175aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2176aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2177fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2178aec7caa3c40891727164167ece11d552422803d2Chandler Carruth if (S.Context.Target.getLongWidth() == 64) 2179aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2180aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2181aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2182fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 218373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 218473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 218573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2186f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2187f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2188f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2189f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2190f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2191f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2192f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2193f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2194f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 219573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 219873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 219973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2203ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 2204ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2205a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2206ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2208fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 22090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 22101feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2211d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 2212d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 2213d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2214d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2215d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2216e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 22175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 2218d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2219883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2220d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2221d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2224d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2225d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 22261feade8e520be483293dbf55eb57a51720899589Mike Stumpstatic void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 22275bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 22285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 22295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 22305bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 22315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2232bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2233c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 22345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2235883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 22365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 22375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2239cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 22405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 22415bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 22427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattnerstatic void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr, 22437255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner Sema &S) { 22447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 22457255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (Attr.getNumArgs() != 0) { 22467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 22477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 22487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 22497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 22507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner if (!isa<FunctionDecl>(d)) { 22517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2252883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 22537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 22547255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 22557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2256f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2257f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 22587255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 22597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2260ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleConstantAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2261ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2263ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2265ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2267ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2269ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2270883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2272ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2273ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2277ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2278ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2279ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2280ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleDeviceAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2281ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2282ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2283ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2284ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2285ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2286ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2287ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2288ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d) && !isa<VarDecl>(d)) { 2289ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2290883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 2291ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2292ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2293ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2294ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2295ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2296ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2297ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2298ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2299ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2300ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleGlobalAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2301ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2302ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2303ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2304ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2305ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2306ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2307ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2308ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2309ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2310883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2311ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2312ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2313ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 23142c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne FunctionDecl *FD = cast<FunctionDecl>(d); 23152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2316723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 23172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 23182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 23192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 23202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 23212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 23222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 23232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 23242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 23252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 23262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 23272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 23282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2329ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2330ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2331ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2332ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2333ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2334ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2335ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleHostAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2336ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2337ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2338ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2339ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2340ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2341ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2342ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2343ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<FunctionDecl>(d)) { 2344ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2345883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2346ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2347ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2348ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2349ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2350ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2351ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2352ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2353ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2354ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2355ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbournestatic void HandleSharedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2356ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2357ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2358ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2359ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2360ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2361ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2362ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2363ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (!isa<VarDecl>(d)) { 2364ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2365883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2366ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2367ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2368ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2369ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne d->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2370ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2371ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2372ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2373ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2374ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2375cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 237626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 237726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 237826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 237926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 238026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2381bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2382c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 2383c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 238426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2385883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 238626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 238726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2388bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23890130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2390cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2391c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2392c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2393bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2394cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 239526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 239626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 2397711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleCallConvAttr(Decl *d, const AttributeList &attr, Sema &S) { 2398711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 2399711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2400711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // Diagnostic is emitted elsewhere: here we store the (valid) attr 2401e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2402711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 2403711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckCallingConvAttr(attr, CC)) 2404711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2405e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 2407711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2408883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 2409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2410711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2411711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 2413e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 2414711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) FastCallAttr(attr.getLoc(), S.Context)); 2415e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2416e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 2417711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) StdCallAttr(attr.getLoc(), S.Context)); 2418e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2419f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2420711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) ThisCallAttr(attr.getLoc(), S.Context)); 242104633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 2422e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 2423711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) CDeclAttr(attr.getLoc(), S.Context)); 2424e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 242552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2426711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) PascalAttr(attr.getLoc(), S.Context)); 242752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 2428e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 2429e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 2430e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2431e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 2432e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 2433e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 2434f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbournestatic void HandleOpenCLKernelAttr(Decl *d, const AttributeList &Attr, Sema &S){ 2435f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne assert(Attr.isInvalid() == false); 2436f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne d->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context)); 2437f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 2438f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 2439711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2440711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2441711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2442711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2443711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 0) { 2444711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2445711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2446711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2447ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 244855d3aaf9a537888734762170823daf750ea9036dEli Friedman 2449711c52bb20d0c69063b52a99826fb7d2835501f1John McCall // TODO: diagnose uses of these conventions on the wrong target. 2450711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 2451711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 2452711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 2453711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 2454711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 2455711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 2456711c52bb20d0c69063b52a99826fb7d2835501f1John McCall default: llvm_unreachable("unexpected attribute kind"); return true; 2457711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2458711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2459711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 2460711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 2461711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2462711c52bb20d0c69063b52a99826fb7d2835501f1John McCallstatic void HandleRegparmAttr(Decl *d, const AttributeList &attr, Sema &S) { 2463711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (hasDeclarator(d)) return; 2464711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2465711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 2466711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckRegparmAttr(attr, numParams)) 2467711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2468711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2469711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (!isa<ObjCMethodDecl>(d)) { 2470711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2471883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 2472ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 2473ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 247455d3aaf9a537888734762170823daf750ea9036dEli Friedman 2475711c52bb20d0c69063b52a99826fb7d2835501f1John McCall d->addAttr(::new (S.Context) RegparmAttr(attr.getLoc(), S.Context, numParams)); 2476711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 2477711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2478711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 2479711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 2480711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckRegparmAttr(const AttributeList &attr, unsigned &numParams) { 2481711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2482711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2483711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2484711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.getNumArgs() != 1) { 2485711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2486711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2487711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2488711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2489711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2490711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Expr *NumParamsExpr = attr.getArg(0); 249155d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 2492ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 2493711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 2494711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_argument_not_int) 249555d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 2496711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2497711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 249855d3aaf9a537888734762170823daf750ea9036dEli Friedman } 249955d3aaf9a537888734762170823daf750ea9036dEli Friedman 2500711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (Context.Target.getRegParmMax() == 0) { 2501711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 250255d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 2503711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2504711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 250555d3aaf9a537888734762170823daf750ea9036dEli Friedman } 250655d3aaf9a537888734762170823daf750ea9036dEli Friedman 2507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 2508711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (numParams > Context.Target.getRegParmMax()) { 2509711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_regparm_invalid_number) 2510711c52bb20d0c69063b52a99826fb7d2835501f1John McCall << Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 2511711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2512711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 251355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 251455d3aaf9a537888734762170823daf750ea9036dEli Friedman 2515711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 2516ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 2517ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 25187b381985353304a7723acb05911ff91634fa1f27Peter Collingbournestatic void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){ 25197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 25207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 25217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 2522bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 2523bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 25247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 25257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 25277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (!isFunctionOrMethod(d)) { 25287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2529883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 25307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 25317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 25337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 25347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 25357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 25367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 25377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 25387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 25397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 25407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 25417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 25437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 25447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 25457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 25467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 25477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 25487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 25497b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 25507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 25517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 25527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 25557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne d->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 25567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 25577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 25587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 25597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 25607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 25617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 25627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 25630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 2564b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 2565b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 2566b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2567c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 2568c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type); 2569c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2570c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 2571c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isPointerType() || isValidSubjectOfNSAttribute(S, type); 2572c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2573c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2574c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumedAttr(Decl *d, const AttributeList &attr, Sema &S) { 2575c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall ParmVarDecl *param = dyn_cast<ParmVarDecl>(d); 2576c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 2577c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2578883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << ExpectedParameter; 2579c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2580c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2581c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2582c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 2583c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (attr.getKind() == AttributeList::AT_ns_consumed) { 2584c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 2585c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 2586c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 2587c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 2588c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 2589c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2590c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2591c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 2592c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 2593c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << cf; 2594c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2595c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2596c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2597c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 2598c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall param->addAttr(::new (S.Context) CFConsumedAttr(attr.getLoc(), S.Context)); 2599c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 2600c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall param->addAttr(::new (S.Context) NSConsumedAttr(attr.getLoc(), S.Context)); 2601c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2602c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2603c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSConsumesSelfAttr(Decl *d, const AttributeList &attr, 2604c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall Sema &S) { 2605c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!isa<ObjCMethodDecl>(d)) { 2606c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2607883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << SourceRange(attr.getLoc()) << attr.getName() << ExpectedMethod; 2608c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 2609c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2610c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2611c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSConsumesSelfAttr(attr.getLoc(), S.Context)); 2612c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 2613c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2614c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &attr, 2615b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 2616b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2617c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 2618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 26195dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 2620c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 26215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 2622c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 26235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 262421531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_attribute_wrong_decl_type) 2625c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) << attr.getName() 2626883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 2627b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2628b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 2629bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2630c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 2631c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 2632c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall switch (attr.getKind()) { 2633c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall default: llvm_unreachable("invalid ownership attribute"); return; 2634c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 2635c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 2636c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 2637c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 2638c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 2639c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 2640c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2641c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 2642c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 2643c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 2644c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 2645c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 2646c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 2647c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2648c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 264921531fa592cd76e5d3df839ce469bea918404ac8Ted Kremenek S.Diag(d->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 2650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << SourceRange(attr.getLoc()) 2651c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall << attr.getName() << isa<ObjCMethodDecl>(d) << cf; 2652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 26535dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 2654bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2655c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall switch (attr.getKind()) { 2656b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 2657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 2658b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2659c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 2660c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(attr.getLoc(), 2661c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 2662c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 266331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2664c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(attr.getLoc(), 2665f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 266631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 266731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 2668c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(attr.getLoc(), 2669f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 267031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 2671b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2672c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) CFReturnsRetainedAttr(attr.getLoc(), 2673f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2674b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2675b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2676c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall d->addAttr(::new (S.Context) NSReturnsRetainedAttr(attr.getLoc(), 2677f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 2678b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 2679b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 2680b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 2681b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2682f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 2683f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 268411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_dllexport || 268511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_uuid; 268611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 268711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 268811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 268911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 269011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 269111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 269211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichetstatic void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) { 269311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet if (S.LangOpts.Microsoft || S.LangOpts.Borland) { 269411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 269511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet if (Attr.getNumArgs() != 1) { 269611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 269711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 269811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet } 269911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 270011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2701d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (Str == 0 || Str->isWide()) { 2702d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2703d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 2704d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2705d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2706d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2707d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet llvm::StringRef StrRef = Str->getString(); 2708d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2709d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 2710d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 2711d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2712d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 2713d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 2714d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2715d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2716d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2717d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 2718d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2719d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2720d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2721d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 2722d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 2723d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 2724f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson llvm::StringRef::iterator I = StrRef.begin(); 2725f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 2726f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 2727f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 2728f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 2729d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 2730d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 2731d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2732d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2733d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2734d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 2735d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 2736d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 2737d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 2738d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 2739d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 274011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 274111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context, 274211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 2743d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 274411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 2745f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 2746f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 2747b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 27480744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 27490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 27500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 275160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessNonInheritableDeclAttr(Scope *scope, Decl *D, 275260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S) { 275360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 275460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: HandleDeviceAttr (D, Attr, S); break; 275560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: HandleHostAttr (D, Attr, S); break; 275660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 275760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 275860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 275960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 276060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 2761e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 276260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessInheritableDeclAttr(Scope *scope, Decl *D, 276360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S) { 2764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 276563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek case AttributeList::AT_IBAction: HandleIBAction(D, Attr, S); break; 2766857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutlet: HandleIBOutlet(D, Attr, S); break; 2767857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 2768857e918a8a40deb128840308a318bf623d68295fTed Kremenek HandleIBOutletCollection(D, Attr, S); break; 2769803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 2770207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 2771ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 27726e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 27734211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 27744211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 2775bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 2776bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 2777803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 277860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 277960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 278060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 278160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 278260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 278360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 27847725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 27857725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 2786bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 2787af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 2788b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 2789bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 27907725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 27910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor case AttributeList::AT_availability:HandleAvailabilityAttr(D, Attr, S); break; 2792bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 27937725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt HandleDependencyAttr (D, Attr, S); break; 2794a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_common: HandleCommonAttr (D, Attr, S); break; 2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_constant: HandleConstantAttr (D, Attr, S); break; 27967725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break; 27977725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break; 27987725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break; 27993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 28009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 28013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 28027725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 28037725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 2804ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_global: HandleGlobalAttr (D, Attr, S); break; 28057725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break; 28067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 28077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne HandleLaunchBoundsAttr(D, Attr, S); 28087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 28097725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 28107725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break; 281134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman case AttributeList::AT_may_alias: HandleMayAliasAttr (D, Attr, S); break; 2812a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher case AttributeList::AT_nocommon: HandleNoCommonAttr (D, Attr, S); break; 28137725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 2814dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 2815dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 2816dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 2817dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek HandleOwnershipAttr (D, Attr, S); break; 2818dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar case AttributeList::AT_naked: HandleNakedAttr (D, Attr, S); break; 28197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 28207725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 2821ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne case AttributeList::AT_shared: HandleSharedAttr (D, Attr, S); break; 282235cc9627340b15232139b3c43fcde5973e7fad30John Thompson case AttributeList::AT_vecreturn: HandleVecReturnAttr (D, Attr, S); break; 2823b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 2824b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 2825c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 2826c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumed: HandleNSConsumedAttr (D, Attr, S); break; 2827c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 2828c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall HandleNSConsumesSelfAttr(D, Attr, S); break; 2829c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 2830c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 283131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 283231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 2833b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 2834b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 2835b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 2836b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 28376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 28386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 28396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2840521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 2841521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian HandleInitPriorityAttr(D, Attr, S); break; 2842521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 28437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 28447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 28457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break; 28467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 28477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 28487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break; 2849026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 2850026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 28517725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 285211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola case AttributeList::AT_weakref: HandleWeakRefAttr (D, Attr, S); break; 28537725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break; 2854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 2855803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 2856803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 28570db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 28580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 28590db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 2860d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 2861d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall HandleObjCMethodFamilyAttr(D, Attr, S); 2862d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 28637725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 28647725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 28657725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 28667725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 28677725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 28687725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 28697725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break; 28707725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break; 28717725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 2872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 287305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 287405f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 28757255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 28767255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner HandleNoInstrumentFunctionAttr(D, Attr, S); 28777255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 287804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 287904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 288004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 2881f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 288252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2883e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara HandleCallConvAttr(D, Attr, S); 288404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 2885f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 2886f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne HandleOpenCLKernelAttr(D, Attr, S); 2887f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 288811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 288911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet HandleUuidAttr(D, Attr, S); 289011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 2891803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 289282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 289382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 289482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 28957d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 28967d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 2897803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 2898803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2899803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2900803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 290160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 290260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 290360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 290460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 290560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournestatic void ProcessDeclAttribute(Scope *scope, Decl *D, 290660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList &Attr, Sema &S, 290760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 290860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 290960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 291060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 291160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 291260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 291360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 291460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 291560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 291660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessNonInheritableDeclAttr(scope, D, Attr, S); 291760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 291860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 291960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessInheritableDeclAttr(scope, D, Attr, S); 292060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 292160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 2922803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 2923803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 2924f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 292560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 292660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 292711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 292860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttribute(S, D, *l, *this, NonInheritable, Inheritable); 292911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 293011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 293111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 293211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 293311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 293460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 293511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 2936dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 293711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 2938803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 2939803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 2940803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 2941e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 2942e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 29431eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) { 29447b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 2945e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 2946e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 2947e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 2948ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara FD->getInnerLocStart(), 2949e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 2950a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall FD->getType(), FD->getTypeSourceInfo()); 2951b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (FD->getQualifier()) { 2952b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall FunctionDecl *NewFD = cast<FunctionDecl>(NewD); 2953c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 2954b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2955e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 2956e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 2957ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 2958a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 295916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 296016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 2961b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 2962b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 2963c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 2964b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 2965e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2966e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 2967e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2968e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 2969e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 2970e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 29717b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 2972c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 2973c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 2974c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 2975c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 2976c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 2977cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 2978cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 2979cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2980c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 2981c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 2982c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 2983c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 2984c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 2985c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 2986c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 2987c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 2988cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 2989e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 2990e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 2991e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 29920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 29930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 29940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 299560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 299660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 2997d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 2998d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 299960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && !WeakUndeclaredIdentifiers.empty()) { 3000d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 3001d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (IdentifierInfo *Id = ND->getIdentifier()) { 3002d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 3003d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall = WeakUndeclaredIdentifiers.find(Id); 3004d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 3005d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakInfo W = I->second; 3006d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall DeclApplyPragmaWeak(S, ND, W); 3007d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall WeakUndeclaredIdentifiers[Id] = W; 3008d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 3009e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3010e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3011e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3012e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 30130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 30147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 301560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3016bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 30170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 30180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 30190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 30200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 30210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 30220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 302360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3024bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 30250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 30260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 302760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 30280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 302954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3030eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the 3031eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type. 3032eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 3033eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize <= StackCapacity); 3034eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3035eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Grow the stack if necessary. 3036eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackSize == StackCapacity) { 3037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall unsigned newCapacity = 2 * StackCapacity + 2; 3038eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 3039eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall const char *oldBuffer = (const char*) Stack; 3040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3041eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackCapacity) 3042eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 3043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall delete[] oldBuffer; 3045eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 3046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall StackCapacity = newCapacity; 3047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall } 3048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize < StackCapacity); 3050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall new (&Stack[StackSize++]) DelayedDiagnostic(diag); 305154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 305254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 3054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Decl *decl) { 3055eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics &DD = S.DelayedDiagnostics; 305654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Check the invariants. 3058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.StackSize >= state.SavedStackSize); 3059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(state.SavedStackSize >= DD.ActiveStackBase); 3060eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.ParsingDepth > 0); 306154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3062eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Drop the parsing depth. 3063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.ParsingDepth--; 306454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3065eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // If there are no active diagnostics, we're done. 3066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DD.StackSize == DD.ActiveStackBase) 3067eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return; 306858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 30692f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 30702f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 3071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (decl) { 3072eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // We emit all the active diagnostics, not just those starting 3073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // from the saved state. The idea is this: we get one push for a 30742f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 30752f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 30762f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 30772f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 30782f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 3079eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 3080eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostic &diag = DD.Stack[i]; 3081eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 30822f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 30832f514480c448708ec382a684cf5e035d3a827ec8John McCall 3084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 30852f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 3086eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedDeprecationCheck(diag, decl); 30872f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 30882f514480c448708ec382a684cf5e035d3a827ec8John McCall 30892f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 3090eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedAccessCheck(diag, decl); 30912f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 309254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 309354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 309454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 309554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 309658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 3097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 3098eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.Stack[i].destroy(); 309958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 3100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.StackSize = state.SavedStackSize; 31012f514480c448708ec382a684cf5e035d3a827ec8John McCall} 31022f514480c448708ec382a684cf5e035d3a827ec8John McCall 31032f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 31042f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 31050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 31062f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 31072f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 31082f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 31092f514480c448708ec382a684cf5e035d3a827ec8John McCall} 31102f514480c448708ec382a684cf5e035d3a827ec8John McCall 31119c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 31122f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 31132f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 31142f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 31152f514480c448708ec382a684cf5e035d3a827ec8John McCall 31162f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 3117ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 3118c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 3119ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 3120ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 3121c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 3122c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 3123ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 312454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 312554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3126ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramervoid Sema::EmitDeprecationWarning(NamedDecl *D, llvm::StringRef Message, 31278e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 3128743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne bool UnknownObjCClass) { 312954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 3130eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 3131eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); 313254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 313354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 313454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 313554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 313654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 313754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 3138ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 3139c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 3140c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 31418e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 3142743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 31438e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 31448e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else 31458e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 31468e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 314754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 3148