SemaDeclAttr.cpp revision ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3
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" 18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h" 19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 25797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 31b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind { 32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameterOrMethod, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassOrVirtualMethod, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVirtualMethod, 43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassMember, 44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 46db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedVariableFunctionOrLabel, 47db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedFieldOrGlobalVar 48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall}; 49883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall 50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 53e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 5487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D, 55a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 6187c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 65bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 68755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 696217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 71183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 77d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 78a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 7987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) { 8087c44604325578b8de07d768391c1c9432404f5aChandler Carruth return getFunctionType(D, false) != NULL; 81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 8687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) { 8787c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isFunction(D)|| isa<ObjCMethodDecl>(D); 88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 9387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) { 9487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethod(D)) 95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 9787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 10187c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<BlockDecl>(D); 102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 103620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 10687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) { 107f85e193739c953358c865005855253af4f68a497John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 10987c44604325578b8de07d768391c1c9432404f5aChandler Carruth isa<ObjCPropertyDecl>(D); 110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 113d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 114620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 11587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) { 11687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 11772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 118620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 11987c44604325578b8de07d768391c1c9432404f5aChandler Carruth assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 126d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 12787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) { 12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 12972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 131d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 13287c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_size(); 1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 13587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 13772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 13887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 139d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14187c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 14487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) { 14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 14787c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->getResultType(); 1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 15087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) { 15187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) { 15272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 15487c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 155db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 156d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 15787c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->isVariadic(); 1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 16187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) { 16287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 16607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 168183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 169b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 173506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 176506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1846217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 193465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 198085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May 200b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth unsigned int Num) { 2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (Attr.getNumArgs() != Num) { 2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return false; 2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth } 2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return true; 2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth} 2101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 211db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May 213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int Num) { 216b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (Attr.getNumArgs() < Num) { 217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return false; 219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return true; 222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 224db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// 225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var 226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable 227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 22839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) { 229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (isa<FieldDecl>(D)) 230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 23139997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 236fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool. 238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) { 239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = Exp->getType(); 240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return QT->isBooleanType() || QT->isIntegerType(); 241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 242b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 243fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type. 245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message. 246fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise 247fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 24839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) { 24939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 250fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski QualType QT = vd->getType(); 25139997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (QT->isAnyPointerType()) 252fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type) 254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName()->getName() << QT; 255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } else { 256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName(); 258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 262b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points 263b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit. 2647d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) { 2657d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const RecordType *RT = QT->getAs<RecordType>()) 266b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return RT; 2677d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer // Now check if we point to record type. 2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const PointerType *PT = QT->getAs<PointerType>()) 2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return PT->getPointeeType()->getAs<RecordType>(); 2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2727d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return 0; 273b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 274b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 2753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType 2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// resolves to a lockable object. May flag an error. 277d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramerstatic bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 278d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer const RecordType *RT) { 2793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Flag error if could not get record type for this argument. 280d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT) { 2813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class) 2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski << Attr.getName(); 2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return false; 2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Flag error if the type is not lockable. 286d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT->getDecl()->getAttr<LockableAttr>()) { 2873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable) 2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski << Attr.getName(); 2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return false; 2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return true; 2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski} 2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 294b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error. 2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with. 2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function 2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list. 2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const AttributeList &Attr, 3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVectorImpl<Expr*> &Args, 302b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski int Sidx = 0, 303b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool ParamIdxOk = false) { 3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski Expr *ArgExp = Attr.getArg(Idx); 3063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 307ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski if (ArgExp->isTypeDependent()) { 308ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski // FIXME -- need to processs this again on template instantiation 309ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski Args.push_back(ArgExp); 310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski continue; 311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski } 312b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 314b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 317b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 321b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 322b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 3253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return false; 331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 3323ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski RT = getRecordType(ArgTy); 334b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, RT)) 338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return false; 339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return true; 343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 345e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 346e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 347e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 348e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 3493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 3503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 3513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 3523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 353fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool pointer = false) { 355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 363b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer && !checkIsPointer(S, D, Attr)) 368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer) 371fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getLoc(), S.Context)); 372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getLoc(), S.Context)); 374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 376db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 377b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool pointer = false) { 378db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 380b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 381db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 3833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 385db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 388b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer && !checkIsPointer(S, D, Attr)) 393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 396ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski // FIXME: handle attributes with dependent types 3973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return; 3983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 3993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 401b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 402b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer) 4043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getLoc(), 4053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, Arg)); 406db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 4073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) GuardedByAttr(Attr.getLoc(), S.Context, Arg)); 408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 411fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool scoped = false) { 413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedClass; 421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (scoped) 425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getLoc(), S.Context)); 426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski D->addAttr(::new (S.Context) LockableAttr(Attr.getLoc(), S.Context)); 428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 437b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getLoc(), 444fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 447db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 448db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski bool before) { 449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 451b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 455b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 456b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 459db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 462b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // Check that this attribute only applies to lockable types 463b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 467b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable) 468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 474b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 4753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 476b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 477b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 4793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 4803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 4813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 482db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (before) 4833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getLoc(), S.Context, 4843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 4863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getLoc(), S.Context, 4873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 492db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 496b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 497b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 498db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 499db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 500db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 503b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 5053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 506b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 507b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getLoc(), 5143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getLoc(), 5183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 523b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 529b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 530b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 531db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 536b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 537b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 539b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 541b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 2> Args; 5433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(Attr.getArg(0)); //FIXME 544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1)) 546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getLoc(), 5543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, 5553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getLoc(), 5583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 563b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 566b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 569b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 575b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 5773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 578b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 579b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 5823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getLoc(), 5863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getLoc(), 5903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 592db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 595b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 600b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 602db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 606b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 6083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 609b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 610b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 6133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getLoc(), S.Context, 6163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 6253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 627b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 628db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 629db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 634b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 635b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 6373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return; 6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 6403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getLoc(), S.Context, Arg)); 641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 644b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 647b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 650b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 656b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 6653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getLoc(), S.Context, 6663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 6711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 67287c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 673545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 674803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 675545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 6799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 6819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 6839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 684f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 685f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 686f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 6874ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 6884ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false); 6894ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 6904ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 6914ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 6924ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 6939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 6949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 6951731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 6969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 6971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 6987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7009cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7019cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 7039ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 705ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 706a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7089cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 7099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 7151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 71887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 719cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 72087c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 7216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 7226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 724803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 725fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 72608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 728cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context)); 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 7303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 73487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 735c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian TD->addAttr(::new (S.Context) MsStructAttr(Attr.getLoc(), S.Context)); 736c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 737c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 738c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 739c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 7401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 74196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 7421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 74396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 74563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 74687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 74763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 74887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context)); 74963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 75063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 75163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7524ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 75363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 75463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 75663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 7571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 75863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 75963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBOutlet attributes only apply to instance variables of 761efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek // Objective-C classes. 76287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D)) { 76387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context)); 76463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 765efbddd23173ea5633cc8a004f1014c68c3ac6593Ted Kremenek } 76663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7674ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 76896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 76996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 7701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 7711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 772857e918a8a40deb128840308a318bf623d68295fTed Kremenek 773857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 774a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 775857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 776857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 777857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 778857e918a8a40deb128840308a318bf623d68295fTed Kremenek 779857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The IBOutletCollection attributes only apply to instance variables of 780857e918a8a40deb128840308a318bf623d68295fTed Kremenek // Objective-C classes. 78187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!(isa<ObjCIvarDecl>(D) || isa<ObjCPropertyDecl>(D))) { 7824ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 783857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 784857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 78587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 7863a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 7873a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 7883a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << VD->getType() << 0; 7893a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 7903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 79187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 7923a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 7933a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 7943a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian << PD->getType() << 1; 7953a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian return; 7963a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian } 7973a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 798a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 799a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 800a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian II = &S.Context.Idents.get("id"); 8013a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 802b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 80387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 804a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 805a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 806a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 807a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 808b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 809a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 810a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 811a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 812a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 813a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCClassType() && 814a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian !QT->isObjCObjectType()) { 815a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 816a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 81887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context, 819cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt QT)); 820857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 821857e918a8a40deb128840308a318bf623d68295fTed Kremenek 822d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 82368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 82468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 82568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 82668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 82768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 82868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 82968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 83068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 83368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 83468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 83568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 83668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 8371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 838bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 839bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 84087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 841fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 842883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 843eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 844eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 845bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 84607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 84707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 84887c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 84987c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 850eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 8525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 854eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 855eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 858eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 8597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 860eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 861ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 862ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 863fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 864fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 865eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 866eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 867bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 868eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 870eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 87230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 876465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 87707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 87807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 87907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 88007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 88107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 88207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 88307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 88407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 88507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 886eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 887eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 88887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 889d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 89068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 891dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 892eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 893c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 894fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 8957fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 896eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 898eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 899eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 900bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 901bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 902bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 9037fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 90487c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 90587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 906d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 907dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 908d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 90946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 910bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 911ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 91260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 91360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 91460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 91560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 91660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 9177fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 91860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 919eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 9207fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 9217fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 9227fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 923dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 92487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start, 925cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 927eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 9281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 929dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 931dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 932dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 933dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 934dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 9352a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 9362a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 942dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 943dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 944cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 9452a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 9462a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 947cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9522a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 954cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 955dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 961cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9682a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 9692a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 9702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 97387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 974883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 977dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 97907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 98007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 98187c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 98287c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 987dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 988dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 991dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9922a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 9932a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 997dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 999dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1000dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 101207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 101307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 101407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 101507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 101607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 101707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 101807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 101907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 102007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1022cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1023cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 102587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1029cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1036cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 10397a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1043dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1047dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 10512a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 10522a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1056cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 105787c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 105887c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1060cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1061cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1062cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1064cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1065cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1076cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 108287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1086332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1087332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1088332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1089332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1090332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1091332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1092332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1093332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1099332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1100332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1101332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 110311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 110411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 110511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 110711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 110811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 110911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 111011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 111111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 111387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1115883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 111987c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 112111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 112311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 113187c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 11327a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 11337a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1134332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 11357a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1156332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1157332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 11667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11705cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 117787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 1178f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 118187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context)); 118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1186545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 11873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11917a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 11926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1194bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11955cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 11973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 11986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1201bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1202f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1203f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1204f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1205f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 120887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, 1209f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 12106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1213dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 12141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1215dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1216dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 121787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1218dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1219883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1220dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1221dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1222dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 122387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NakedAttr(Attr.getLoc(), S.Context)); 1224dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1225dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 12261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 12271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1229831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 12303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1231af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1232af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 12335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 123487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 12355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1236883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 12375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 12385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1239bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 124087c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context)); 1241af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1242af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 12431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1244dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1245831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 124676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 124776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 124876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 125087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 12511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 12522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 125387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context)); 12542cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 12552cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1256fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1257fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 12582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 125976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 126076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 12611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 126234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 12631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 126434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 126534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 126687c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) MayAliasAttr(Attr.getLoc(), S.Context)); 126734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 126834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 12691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 127056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 127187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 127287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoCommonAttr(Attr.getLoc(), S.Context)); 1273722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1274722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1275883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1276a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1277a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 12781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 127956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 128087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 128187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CommonAttr(Attr.getLoc(), S.Context)); 1282722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1283722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1284883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1285a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1286a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 12871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 128887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1289711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1290711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1291711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 129287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1293711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1294883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1295711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1296711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 129887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoReturnAttr(attr.getLoc(), S.Context)); 1299711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1301711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1302831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1303711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1309b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1310b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 13121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1313b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1314b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1315b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 1316b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 13181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 1319b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 132087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 132187c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 13223ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 13233ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1325e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1326b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1327883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1328b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 132919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 13306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1331b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 133287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context)); 13336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 133535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 13361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 133735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 133835cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 133935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 1340f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 1341f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1342f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1343f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1344f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 134535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 134635cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 134735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 134835cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 134935cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 135135cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 135835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 136087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1362883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 136687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 137187c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 137201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 137301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 137401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 137501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 137601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 137701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 137801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 137901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 138001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 138101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1384f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1385f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 138601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 139387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context)); 139435cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 139535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 13961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 139787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1398bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1399883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 14051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 140673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1407831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 14083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 140973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 141073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 141287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 141387c44604325578b8de07d768391c1c9432404f5aChandler Carruth !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 1414fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1415883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 141673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 141773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1418bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 141987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context)); 142073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 142173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 14221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1423b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1424831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1425b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1426b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1427b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1428bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 142987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1430186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1431b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1432b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1433b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 143487c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1435b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1436883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1437b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1438b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 144087c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); 1441b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1442b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 14431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1445bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1446bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 14473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1448bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 14513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 14527a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 14533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1454ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1455ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1456fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 14583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 14613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1462bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 146387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1464fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1465883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 14663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 146987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, 1470f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 14713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 14723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1475bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1476bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 14773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1478bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 14827a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1484ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1485ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1486fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 14883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1492bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 149387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1494fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1495883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 14963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 149987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, 1500f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1504951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1505951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1506bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1507c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1508c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1509951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1510c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 15115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1512951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1513951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1514c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1515951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1516951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner << "deprecated"; 1517c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1518c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1519951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 15206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 152287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context, Str)); 15236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1526951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1527951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1528bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1529bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1530bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1531951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1532c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 15335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1534951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1535951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1536c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), 1538c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1539c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1540c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1541951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 1542c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 154387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str)); 1544bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1545bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1546742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1547742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1548742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1549742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1550742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1551742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1552742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 1553742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1554742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1555742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian Attr.getLoc(), S.Context)); 1556742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1557742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 15581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D, 15591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 15600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor IdentifierInfo *Platform = Attr.getParameterName(); 15610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SourceLocation PlatformLoc = Attr.getParameterLoc(); 15620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 15640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 15650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (PlatformName.empty()) { 15660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 15670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << Platform; 15680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 15700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 15710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 15730a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 15740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 1575b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 15760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1577c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 15780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 15790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Deprecated.isValid() && 15803b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Deprecated.Version)) { 15810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 15820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << PlatformName << Deprecated.Version.getAsString() 15830a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 15840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 15850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 15860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Obsoleted.isValid() && 15883b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Obsoleted.Version)) { 15890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 15900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 15910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 15920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 15930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 15940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Deprecated.isValid() && Obsoleted.isValid() && 15963b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Deprecated.Version <= Obsoleted.Version)) { 15970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 15990a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << Deprecated.Version.getAsString(); 16000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 160387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getLoc(), S.Context, 16040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Platform, 16050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Introduced.Version, 16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Deprecated.Version, 1607b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor Obsoleted.Version, 1608b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor IsUnavailable)); 16090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 16100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 16131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 16146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1615bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 16176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 16186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1619bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16205cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1621fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 16223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 16236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1625bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 1627cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1628bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1629c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1630cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1631c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1632cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1633c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1634cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 1635c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 1636cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 16376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 163808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 16396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1641bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 164287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type)); 16436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 16461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1647d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1648d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 164987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1650883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 1651d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1652d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1653d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 165487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 165587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 165687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1657d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 1658d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 165987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1660d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 166187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 1662d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1663d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1664d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 16655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 1666d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 1667d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 1668d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 1669d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 1670d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 1671d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 1672d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 1673d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 1674d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 1675d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 1676d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1677d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 1678d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 1679d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 1680d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 1681d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 168287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 1683d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1684d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1685d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1686f85e193739c953358c865005855253af4f68a497John McCall if (family == ObjCMethodFamilyAttr::OMF_init && 1687f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 1688f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 1689f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 1690f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 1691f85e193739c953358c865005855253af4f68a497John McCall return; 1692f85e193739c953358c865005855253af4f68a497John McCall } 1693f85e193739c953358c865005855253af4f68a497John McCall 169487c44604325578b8de07d768391c1c9432404f5aChandler Carruth method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getLoc(), 1695f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 1696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 1697d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 16981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 16991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 17001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 17010db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 1702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 17040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 17050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 17060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 17070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1708bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1709cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context)); 17100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 17110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 17121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 1713fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 17142b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1715fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1716fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1717162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 1718fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1719fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 17206217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1721fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1722fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1723fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1724fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1725cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context)); 1726fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1727fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1728bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 17291b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1730f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 17312b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1732f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1733f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1734f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1735f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1736f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1737f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1738f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1739f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1740cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context)); 1741f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1742f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 17431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1745fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 17463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 17479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1749bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 17513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 17529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1754bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1755cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 175692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 17579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 17589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1759fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 17603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 17619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1763bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 176487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type)); 17659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 17669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 17671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1768770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1769770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1770bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1771770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1772bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1773bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1774770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 1775770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 17767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1777770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1778ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1779ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1780fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 17813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1782770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1783770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1784770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 1785bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1786770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 1787fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1788fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1789770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1790770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1791770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1792770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 1793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 1794770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 17957a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1796770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1797ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1798ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1799fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1801770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1802770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1803770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1804bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1805770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 1806770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1807770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1809fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1810770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1811770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1812770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1813770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 181487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1815183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const FunctionType *FT = FD->getType()->getAs<FunctionType>(); 1816897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 1817bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1818897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1819897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1820897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1821897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1822bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1823897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 18243bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1825770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 182787c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 1828770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 18293bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1830770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 18312f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 183287c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (isa<BlockDecl>(D)) { 1833bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1834bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 18352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 183687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 18372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1838daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 183987c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 1840f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 18412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 18423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 18433bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 18442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 18452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1846ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 18472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1848883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 18492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 18502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1852fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1853883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1854770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1855770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 185687c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, 1857f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1858770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 18601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 1861026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 18621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1863026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1864026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1865f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1866026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1867883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 1868026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1869026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1870bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1871f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1872f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1873f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1874f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1875f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1876f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1877f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1878f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1879f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1880f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1881f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1882f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1883cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context)); 1884026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1885026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 18861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 18876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 188887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 188987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 18906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 18916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 18926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 189387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 189487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 189587c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 1896f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1897f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1898f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 189987c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1900332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1901332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 1902332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 190387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 19046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 190787c44604325578b8de07d768391c1c9432404f5aChandler Carruth nd->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context)); 19086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 19096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 19121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 19136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 19156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 19176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 19180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 19190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 19200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 19210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 19220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 1923def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 1924bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 1925def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor isa<ObjCInterfaceDecl>(D))) { 1926def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 1927def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 1928c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1929883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 19306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 19336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1934cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context)); 19356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 19366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D, 19381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 19396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 19401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 3)) 19416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 19426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 19436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 19446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 19457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 19466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1947ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1948ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 19496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 19506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 19516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 19526f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 19536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 19546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context, 1956cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 19576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 19586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 19596f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 19601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 196117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 19621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 196317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 196417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 196517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 196617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 19677a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1968797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 196917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1970797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 197117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 197217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1974797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 1975bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 1976a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 1977a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 1978a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 1979797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 1980797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 19811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1982a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 1983a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 1984a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 1985a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 1986a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 1987a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 1988f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, 1989f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 199017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 199117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 19926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1995831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 19963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1999b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 200087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2001b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2002b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor Existing->setLocation(Attr.getLoc()); 2003b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 200487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); 2005b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 20066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2009232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2010831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 20113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2012232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2013232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2014bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 201587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2016b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2017b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor Existing->setLocation(Attr.getLoc()); 2018b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 201987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); 2020b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2021232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2022232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 20231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2024232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 20251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2026232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2027bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 202887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context)); 2029232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2030232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 20311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2033f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2035f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2036bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2037f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2038f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2039f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2040f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2041bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 204287c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2043bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2044f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2045f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2046f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2047f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2048bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2049f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2050c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2051f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2052f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2053f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2054f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2055f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2058f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2059bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2062f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2063f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2064f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2066f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2067f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2069f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2070f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2071f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2072f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2073f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2074bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 207589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 207689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 207789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 207889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2079b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2080b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2081f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 208289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 208389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 208489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 208589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 208787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD)); 2088223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 2089f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2091bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2092bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 20931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 20955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 20961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 209787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 20985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2099883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 21005b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 210207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 210307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 210407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 210587c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 210687c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 21075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 210807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 21095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 21107a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 21115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2112ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2113ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 21145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 21155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 21165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 21205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 21215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 21225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2126bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 212707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 212807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 212907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 213007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 213107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 213207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 213307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 213407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 213507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 21365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 213787c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 21405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 21415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 21425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 21436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 21445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 21455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2146bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 21475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 21485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2149bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 215087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 21515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 21525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 21535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 21546217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 21555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 21565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2157bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 21585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 21595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2161bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 216287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, 216307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 21645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 21655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 21662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 21672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 21682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 21692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 21702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 21713c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 21722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 21732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 21742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 21752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 21762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 21775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 21782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 21792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 21802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 21812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 21822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 21832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 21842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 21852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 21862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 21872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 21882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 21892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 2190cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "zcmn_err" || 2191cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "kprintf") // OpenBSD. 21922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 21932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2194bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 2195bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 21963c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 21973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 21982b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 21992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 22002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2201521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2202521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 22031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 22041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 2205521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 2206521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2207521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2208521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2209521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 221087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2211b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2212b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2213b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2214b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 221587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2216b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2217b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2218b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2219b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2220b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2221b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2222b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 2223b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2224521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2225521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2226521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2227521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2228521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 22297a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 2230b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2231521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2232521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2233521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2234521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2235521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2236521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2237521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2238521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 22399f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2240521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2241521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2242521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2243521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2244521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2245521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 224687c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, 2247f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2248521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2249521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2251bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 22521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 22536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2254545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2255fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 22563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 22576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2260545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 22613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 22626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 226587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2266fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2267883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 22686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 227107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 227207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 227387c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 227487c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 22756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 22766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 22786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 22812b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 22822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 22853c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 22863c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 22873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 22883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2290fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 229101eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 22967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2297803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2298ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2299ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2300fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2306fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 23073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 23126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2313bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23144a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 23154a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 231607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 231707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 231807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 23194a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 23204a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 23214a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 23224a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 23231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 232587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 23266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2328085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2329fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2330fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2331085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2332085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 23332b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2334390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2335390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2336803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2337390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2339fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 23406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 23426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 23436217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2344390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2345fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2346fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 23476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 23517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2352803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2353ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2354ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2355fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 23576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 236287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 23636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 23646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 236587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 23713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 23722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 2374fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2375fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 23766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 2380fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 23813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2385b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // Check whether we already have an equivalent format attribute. 2386b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor for (specific_attr_iterator<FormatAttr> 238787c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<FormatAttr>(), 238887c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<FormatAttr>(); 2389b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor i != e ; ++i) { 2390b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor FormatAttr *f = *i; 2391b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getType() == Format && 2392b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFormatIdx() == (int)Idx.getZExtValue() && 2393b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFirstArg() == (int)FirstArg.getZExtValue()) { 2394b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // If we don't have a valid location for this attribute, adopt the 2395b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // location. 2396b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getLocation().isInvalid()) 2397b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->setLocation(Attr.getLoc()); 2398b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor return; 2399b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2400b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2401b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 240287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, 2403cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 24042b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 24081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 24101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 24150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 24170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 24180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 24190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 242087c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 24210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 24220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 2423fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2424883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 24256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 2429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 24300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 24310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 24330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 243417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 243517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 24360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 24370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 24380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2440bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 24410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 24420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 244390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 244590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 244690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 24470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2449bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 24500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 24510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 24520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 24530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 24540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 24550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 24560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 24570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2458bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 24590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 2460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 24610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 24620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 24630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 2464bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 24650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 24660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 2467bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 2468bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 2469bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2471cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context)); 24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 24761731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 24776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 24797a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2480797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2481bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 24836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 24846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 2485797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 248887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, 2489f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 24906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 24936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2494545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 24953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 24966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2498bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2499bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 2500bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 2501bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2503545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2504cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0)); 25054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 25064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 25074ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 25087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne S.AddAlignedAttr(Attr.getLoc(), D, Attr.getArg(0)); 25094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 25104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 25114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruthvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { 25124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 25134ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2514cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 25156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2517bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2518cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 251949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 25204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 25214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 25224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 252349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 252449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 2525396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 25264ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 25274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2528396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2529396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2530396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2531cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E)); 2532cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2533cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2534cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Huntvoid Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) { 2535cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2536cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2537cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS)); 2538cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 25396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2540fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2541d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 2542bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2543fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2544bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2545bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2546bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 25471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2548fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2549fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2550fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2551fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 25521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2553fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 25541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2555fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2557fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 25580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2559fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2560fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2561210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 25625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 2563fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2565210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2566210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2567fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2568fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2569fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 257073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2571210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2572fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 257373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 257473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 257573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 257673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 257773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 257873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 257973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 258073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 258173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 258273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 258373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 258473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 258573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 258673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 258773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 258873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 2591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2592fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 2593210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 2594bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2595210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 2596bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 2597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2598fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2599210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 2600bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2601fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2602fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2605162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2606fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2607fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2609fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2610fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2611fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 2612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2613fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 261473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2615183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 261673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 261773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 26182ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 261973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 262073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 262173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 262273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 262373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 262473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 262573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 262673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 262773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2628390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2629390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2630390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2631390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2632f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2633f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2634fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2635fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2636fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 26373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2639fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 26403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2642fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 264373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 264473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 264573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 264673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 26480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2649fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 26500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2651fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2652fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 265373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 265473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 265573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 265673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 26580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2659fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 26600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2663fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 26640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 26660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 26680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2671fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 26720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2674bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2675aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2676aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2677aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2678fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2679bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2680aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2681aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2682aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2683fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2687f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2688f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2689f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2690f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2691f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2692f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2693f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2694f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2695f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 269673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2698fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 269973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 270073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2701fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2704162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2705ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2706a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2707ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 27100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 27111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2712d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 27131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2714d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2715e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 271687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 2717d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2718883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2719d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2720d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2721bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 272287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context)); 2723d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2724d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 27251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 27265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 27271731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 27285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 27291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 273187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 27325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2733883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 27345bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 27355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2736bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 273787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context)); 27385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 27395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 27401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 27411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 27427255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 27431731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 27447255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 27451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 27467255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 274787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 27487255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2749883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 27507255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 27517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 27527255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 275387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), 2754f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 27557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 27567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 27571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2758ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2759ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2760831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 2761ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2762ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2763ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2764ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 276587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2766ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2767883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2768ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2769ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2770ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 277187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getLoc(), S.Context)); 2772ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2773ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2774ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2775ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2776ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 27771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2778ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2779ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2780ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2781ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2782ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2783ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2784ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 278587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2786ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2787883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 2788ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2789ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2790ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 279187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getLoc(), S.Context)); 2792ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2793ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2794ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2795ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2796ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 27971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2798ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2799ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2801ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2802ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 280387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2804ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2805883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2806ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2807ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2808ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 280987c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 28102c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2811723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 28122c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 28132c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 28142c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 28152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 28162c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 28172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 28182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 28192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 28202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 28212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 28222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 28232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 282487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getLoc(), S.Context)); 2825ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2826ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2827ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2828ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2829ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2831ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2832ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 28351731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2836ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 283787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2838ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2839883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2840ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2841ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2842ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 284387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getLoc(), S.Context)); 2844ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2845ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2846ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2847ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2848ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2850ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2851ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2853ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 28541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2855ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 285687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2857ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2858883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2859ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2860ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2861ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 286287c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getLoc(), S.Context)); 2863ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2865ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 286926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 28701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 287126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 2872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 287387c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2874c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 287526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2876883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 287726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 287826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2879bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 28800130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2881cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2882c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2883c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2884bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 288587c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context)); 288626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 288726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 28881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 288987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 2890711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 289187c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2892e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2893711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 289487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 2895711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2896e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 289787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 289887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 289987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 2900711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2901711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2902711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 290387c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 2904e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 290587c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context)); 2906e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2907e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context)); 2909e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2910f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 291187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context)); 291204633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 2913e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 291487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context)); 2915e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 291652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 291787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context)); 291852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 2919414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 292087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *Arg = Attr.getArg(0); 2921414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 29225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 292387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2924414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 292587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2926414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 2927414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2928414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 29295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 2930414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 2931414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") 2932414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 2933414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else if (StrRef == "aapcs-vfp") 2934414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 2935414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else { 293687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2938414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 2939414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2940414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 294187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) PcsAttr(Attr.getLoc(), S.Context, PCS)); 2942414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2943e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 2944e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 2945e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2946e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 2947e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 2948e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 29491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 295056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 295187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getLoc(), S.Context)); 2952f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 2953f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 2954711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2955711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2956711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2957711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2958831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if ((attr.getNumArgs() != 0 && 2959831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 2960831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek attr.getParameterName()) { 2961711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2962711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 2963711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2964ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 296555d3aaf9a537888734762170823daf750ea9036dEli Friedman 2966414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 2967414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 2968711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 2969711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 2970711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 2971711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 2972711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 2973711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 2974414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 2975414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 2976414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 29775cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 2978414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 2979414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 2980414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 2981414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 2982414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2983414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 29845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 2985414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 2986414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 2987414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 2988414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 2989414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 2990414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 2991414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2992414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // FALLS THROUGH 2993414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2994711c52bb20d0c69063b52a99826fb7d2835501f1John McCall default: llvm_unreachable("unexpected attribute kind"); return true; 2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2996711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2997711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 2998711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 2999711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 30001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 300187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3002711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3003711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 300487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3005711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3006711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 300787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 300887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 300987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3010ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3011ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 301255d3aaf9a537888734762170823daf750ea9036dEli Friedman 301387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context, numParams)); 3014711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3015711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3016711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3017711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 301887c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 301987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3020711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3021711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 302287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 302387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 302487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3025711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3026711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3027711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 302955d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3030ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3031711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 303287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 303355d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 303487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3035711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 303655d3aaf9a537888734762170823daf750ea9036dEli Friedman } 303755d3aaf9a537888734762170823daf750ea9036dEli Friedman 3038bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 303987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 304055d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3042711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 304355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 304455d3aaf9a537888734762170823daf750ea9036dEli Friedman 3045711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3046bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 304787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3048bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 304987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3050711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 305155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 305255d3aaf9a537888734762170823daf750ea9036dEli Friedman 3053711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3054ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3055ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 30561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 30577b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 30587b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 30597b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3060bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3061bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 30627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 30637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30647b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 306587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 30667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3067883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 30687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 30697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 30717b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 30727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 30737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 30747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 30757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 30767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 30777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 30787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 30797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 30817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 30827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 30837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 30847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 30857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 30867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 30877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 30887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 30897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 30907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 309387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getLoc(), S.Context, 30947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 30957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 30967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 30977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 30987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 30997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 31007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3102b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3103b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3104b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3105c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 3106c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isObjCObjectPointerType() || S.Context.isObjCNSObjectType(type); 3107c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3108c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 3109c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return type->isPointerType() || isValidSubjectOfNSAttribute(S, type); 3110c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3111c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 311387c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3114c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 311587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 311687c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedParameter; 3117c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3118c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3119c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3120c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 312187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3122c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3123c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3124c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3125c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3126c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3127c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3128c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3129c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 313087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 313187c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(Attr.getLoc()) << Attr.getName() << cf; 3132c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3133c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3134c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3135c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 313687c44604325578b8de07d768391c1c9432404f5aChandler Carruth param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getLoc(), S.Context)); 3137c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getLoc(), S.Context)); 3139c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3140c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 31421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 314387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 314487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(Attr.getLoc()) << Attr.getName() << ExpectedMethod; 3146c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3147c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3148c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 314987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getLoc(), S.Context)); 3150c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3151c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 31531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3154b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3155c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3156bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3158c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 315987c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3160831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian returnType = PD->getType(); 316187c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) && 316287c44604325578b8de07d768391c1c9432404f5aChandler Carruth (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3163f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 316487c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3165c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 31665dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 316787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 316887c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(Attr.getLoc()) << Attr.getName() 3169883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3170b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3171b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3172bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3173c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3174c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 317587c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3176c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall default: llvm_unreachable("invalid ownership attribute"); return; 3177c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3178c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 3179c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 3180c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3181c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3182c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3183c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3184c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 3185c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 3186c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3187c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3188c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3189c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3190c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3191c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 319287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 319387c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(Attr.getLoc()) 319487c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 31965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 319887c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3199b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3200b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 3201b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3202c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 320387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getLoc(), 3204c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3205c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 320631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 320787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), 3208f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 320931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 321031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 321187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), 3212f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 321331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 3214b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 321587c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), 3216f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3217b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3218b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 321987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), 3220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3221b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3222b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3223b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3224b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3225dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3226dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3227dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3228dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3229dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3230dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3231dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall if (!isa<ObjCMethodDecl>(method)) { 3232dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type) 3233dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc, loc) << attr.getName() << 13 /* methods */; 3234dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3235dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3236dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3237dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3238dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 3239dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall if (!resultType->isPointerType() || resultType->isObjCRetainableType()) { 3240dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3241dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3242dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3243dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3244dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3245dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3246dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3247dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3248dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3249dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ::new (S.Context) ObjCReturnsInnerPointerAttr(loc, S.Context)); 3250dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3251dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 32521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 32531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 325487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3255f85e193739c953358c865005855253af4f68a497John McCall 325687c44604325578b8de07d768391c1c9432404f5aChandler Carruth SourceLocation L = Attr.getLoc(); 325787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 325887c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(L, L) << Attr.getName() << 12 /* variable */; 3259f85e193739c953358c865005855253af4f68a497John McCall} 3260f85e193739c953358c865005855253af4f68a497John McCall 32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 32621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 326387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 326487c44604325578b8de07d768391c1c9432404f5aChandler Carruth SourceLocation L = Attr.getLoc(); 326587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 326687c44604325578b8de07d768391c1c9432404f5aChandler Carruth << SourceRange(L, L) << Attr.getName() << 12 /* variable */; 3267f85e193739c953358c865005855253af4f68a497John McCall return; 3268f85e193739c953358c865005855253af4f68a497John McCall } 3269f85e193739c953358c865005855253af4f68a497John McCall 327087c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 3271f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 3272f85e193739c953358c865005855253af4f68a497John McCall 3273f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 3274f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 327587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3276f85e193739c953358c865005855253af4f68a497John McCall << type; 3277f85e193739c953358c865005855253af4f68a497John McCall return; 3278f85e193739c953358c865005855253af4f68a497John McCall } 3279f85e193739c953358c865005855253af4f68a497John McCall 3280f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3281f85e193739c953358c865005855253af4f68a497John McCall 3282f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 3283f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 3284f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3285f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 3286f85e193739c953358c865005855253af4f68a497John McCall 3287f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 3288f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 3289f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 3290f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 3291f85e193739c953358c865005855253af4f68a497John McCall break; 3292f85e193739c953358c865005855253af4f68a497John McCall 3293f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 3294f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 3295f85e193739c953358c865005855253af4f68a497John McCall break; 3296f85e193739c953358c865005855253af4f68a497John McCall 3297f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 3298f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 329987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3300f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 3301f85e193739c953358c865005855253af4f68a497John McCall break; 3302f85e193739c953358c865005855253af4f68a497John McCall } 3303f85e193739c953358c865005855253af4f68a497John McCall 330487c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth ObjCPreciseLifetimeAttr(Attr.getLoc(), S.Context)); 3306f85e193739c953358c865005855253af4f68a497John McCall} 3307f85e193739c953358c865005855253af4f68a497John McCall 3308f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 3309f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 331011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_dllexport || 331111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_uuid; 331211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 331311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 331411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 331511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 331611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 331711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 33181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 331911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet if (S.LangOpts.Microsoft || S.LangOpts.Borland) { 332011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 33211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 332211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 33231731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 332411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 332511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 33265cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3327d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3328d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 3329d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3330d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3331d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 33325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3333d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3334d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3335d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 3336d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3337d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 3338d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 3339d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3340d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3341d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3342d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 3343d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3344d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3345d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3346d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3347d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3348d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 33495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 3350f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 3351f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 3352f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 3353f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 3354d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 3355d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 3356d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3357d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3358d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3359d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 3360d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3361d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3362d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3363d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 3364d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 336511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 336687c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context, 336711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 3368d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 336911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3370f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 3371f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 3372b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 33730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 33740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 33750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 33761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 33771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 337860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 33791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 33801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 33811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 338260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 338360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 338460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 338560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 3386e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 33871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 33881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3389803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 33901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 33911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 3392857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 33931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 3394803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 3395207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 3396ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 33976e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 33984211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 33994211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 3400bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 3401bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 3402803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 340360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 340460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 340560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 340660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 340760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 340860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 34091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 34101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 34121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 3413b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 34141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 34151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 34161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 34181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 34191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 34201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 34211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 34221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 34231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 34243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 34263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 34271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 34281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 34291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 34301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 34317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 34321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 34337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 34351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 34361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 34371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3439dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 3440dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 3441dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 34421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 34431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 34441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 34451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 34461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 34471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3448b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3449b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis case AttributeList::AT_objc_ownership: 34501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 3451f85e193739c953358c865005855253af4f68a497John McCall case AttributeList::AT_objc_precise_lifetime: 34521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3453f85e193739c953358c865005855253af4f68a497John McCall 3454dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall case AttributeList::AT_objc_returns_inner_pointer: 3455dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3456dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3457b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 3458c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 34591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3460c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 34611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 3462c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3463c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 346431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 346531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3466b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3467b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 34681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 3469b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 34706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 34711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleReqdWorkGroupSize(S, D, Attr); break; 34726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 3473521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 34741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 3475521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 34761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 34771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break; 34781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 34791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3480742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian case AttributeList::AT_arc_weakref_unavailable: 3481742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian handleArcWeakrefUnavailableAttr (S, D, Attr); 3482742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 34831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 34841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 34851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 34861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3487026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 34881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 34891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 34901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3491803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 34921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 3493803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 34940db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 34951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 34960db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 3497d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 34981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 3499d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 35001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break; 35011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 35021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 35031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 35041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 35051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 35061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 35071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 35081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3509bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 351005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 351105f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 35127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 35131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 35147255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 351504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 351604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 351704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 3518f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 351952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3520414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: 35211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 352204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 3523f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 35241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 3525f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 352611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 35271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 352811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 3529fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3530fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 3531fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_guarded_var: 3532fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 3533fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3534fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_pt_guarded_var: 3535fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3536fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3537fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_scoped_lockable: 3538fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr, /*scoped = */true); 3539fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3540fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_no_thread_safety_analysis: 3541fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 3542fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3543fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_lockable: 3544fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 3545fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_guarded_by: 3547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 3548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_pt_guarded_by: 3550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_lock_function: 3553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3555db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_locks_required: 3556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3558db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_trylock_function: 3559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3561db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_lock_returned: 3562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 3563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_locks_excluded: 3565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 3566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_lock_function: 3568db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr); 3569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_locks_required: 3571db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr); 3572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_trylock_function: 3574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr); 3575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_unlock_function: 3577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 3578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_before: 3580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_after: 3583db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3585fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3586803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 358782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 358882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 358982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 35907d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 35917d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 3592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 3593803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3595803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 359660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 359760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 359860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 359960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 36001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 360260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 360360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 360460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 360560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 360660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 360760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 360860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 360960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 361060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 361260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 361360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 36141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 361560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 361660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 3617803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3618803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 3619f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 362060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 362160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 362211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 362411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 362511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 362611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 362711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 362811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 362960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 363011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3631dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 363211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 3633803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3634803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3635803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 3636e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3637e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 3638900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3639900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 36407b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3641e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 3642e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3643900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 3644900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 3645900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 3646900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 3647900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 3648900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3649900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 3650900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 3651900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 3652900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 3653900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 3654900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 3655900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 3656900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3657900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 3658c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 3659900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3660900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 3661900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 3662900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 3663900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3664900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 3665900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3666900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 3667900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3668900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 3669900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 3670900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 3671900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD->setParams(Params.data(), Params.size()); 3672b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3673e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3674e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3675ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 3676a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 367716573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 367816573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 3679b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 3680b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 3681c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 3682b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3683e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3684e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 3685e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3686e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 3687e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3688e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 36897b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3690c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 3691c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 3692c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3693c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 3694900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3695cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3696cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 3697cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3698c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 3699c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3700c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 3701c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 3702c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 3703c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 3704c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 3705c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 3706cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3707e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3708e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3709e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 37100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 37110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 37120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 371360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 371460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 3715d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 3716d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 371731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 371831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 371931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 372031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 372131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 372231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 372331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 372431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 372531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 372631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 372731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 372831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 3729d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 3730e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3731e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3732e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3733e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 37340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 37357f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 373660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3737bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 37380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 37390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 37400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 37410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 37420744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 37430744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 374460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3745bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 37460744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 37470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 374860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 37490744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 375054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3751f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 3752f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 3753f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 3754f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 3755f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 3756f85e193739c953358c865005855253af4f68a497John McCall if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl)) 3757f85e193739c953358c865005855253af4f68a497John McCall return false; 3758f85e193739c953358c865005855253af4f68a497John McCall 3759f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 3760f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 3761f85e193739c953358c865005855253af4f68a497John McCall} 3762f85e193739c953358c865005855253af4f68a497John McCall 3763f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 3764f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 3765f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 3766f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 3767f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 3768f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 3769f85e193739c953358c865005855253af4f68a497John McCall return; 3770f85e193739c953358c865005855253af4f68a497John McCall } 3771f85e193739c953358c865005855253af4f68a497John McCall 3772f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 3773f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 3774f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 3775f85e193739c953358c865005855253af4f68a497John McCall} 3776f85e193739c953358c865005855253af4f68a497John McCall 3777eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the 3778eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type. 3779eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 3780eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize <= StackCapacity); 3781eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3782eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Grow the stack if necessary. 3783eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackSize == StackCapacity) { 3784eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall unsigned newCapacity = 2 * StackCapacity + 2; 3785eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 3786eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall const char *oldBuffer = (const char*) Stack; 3787eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3788eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackCapacity) 3789eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 3790eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3791eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall delete[] oldBuffer; 3792eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 3793eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall StackCapacity = newCapacity; 3794eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall } 3795eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3796eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize < StackCapacity); 3797eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall new (&Stack[StackSize++]) DelayedDiagnostic(diag); 379854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 379954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3800eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 3801eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Decl *decl) { 3802eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics &DD = S.DelayedDiagnostics; 380354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3804eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Check the invariants. 3805eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.StackSize >= state.SavedStackSize); 3806eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(state.SavedStackSize >= DD.ActiveStackBase); 3807eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.ParsingDepth > 0); 380854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3809eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Drop the parsing depth. 3810eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.ParsingDepth--; 381154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3812eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // If there are no active diagnostics, we're done. 3813eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DD.StackSize == DD.ActiveStackBase) 3814eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return; 381558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 38162f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 38172f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 3818a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis if (decl && !decl->isInvalidDecl()) { 3819eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // We emit all the active diagnostics, not just those starting 3820eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // from the saved state. The idea is this: we get one push for a 38212f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 38222f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 38232f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 38242f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 38252f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 3826eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 3827eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostic &diag = DD.Stack[i]; 3828eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 38292f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 38302f514480c448708ec382a684cf5e035d3a827ec8John McCall 3831eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 38322f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 3833eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedDeprecationCheck(diag, decl); 38342f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 38352f514480c448708ec382a684cf5e035d3a827ec8John McCall 38362f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 3837eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedAccessCheck(diag, decl); 38382f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 3839f85e193739c953358c865005855253af4f68a497John McCall 3840f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 3841f85e193739c953358c865005855253af4f68a497John McCall handleDelayedForbiddenType(S, diag, decl); 3842f85e193739c953358c865005855253af4f68a497John McCall break; 384354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 384454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 384554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 384654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 384758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 3848eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 384929233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor DD.Stack[i].Destroy(); 385058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 3851eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.StackSize = state.SavedStackSize; 38522f514480c448708ec382a684cf5e035d3a827ec8John McCall} 38532f514480c448708ec382a684cf5e035d3a827ec8John McCall 38542f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 38552f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 38560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 38572f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 38582f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 38592f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 38602f514480c448708ec382a684cf5e035d3a827ec8John McCall} 38612f514480c448708ec382a684cf5e035d3a827ec8John McCall 38629c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 38632f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 38642f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 38652f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 38662f514480c448708ec382a684cf5e035d3a827ec8John McCall 38672f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 3868ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 3869c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 3870ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 3871ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 3872c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 3873c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 3874ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 387554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 387654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 38775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 38788e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 387989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 388054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 3881eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 3882eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); 388354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 388454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 388554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 388654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 388754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall if (isDeclDeprecated(cast<Decl>(CurContext))) 388854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 3889ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 3890c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 3891c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 38928e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 3893743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 38948e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 389589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian else { 38968e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 389789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 389889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian } 38998e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 390054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 3901