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" 17bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins#include "clang/AST/CXXInheritance.h" 18384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 19b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h" 20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 21acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 23fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 26fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h" 27797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 33b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind { 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 44db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedVariableFunctionOrLabel, 45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor ExpectedFieldOrGlobalVar, 465e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg ExpectedStruct, 475e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg ExpectedTLSVar 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) { 874ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky 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 2240d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// \brief Check if IdxExpr is a valid argument index for a function or 2250d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// instance method D. May output an error. 2260d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// 2270d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko/// \returns true if IdxExpr is a valid index. 2280d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D, 2290d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko StringRef AttrName, 2300d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko SourceLocation AttrLoc, 2310d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko unsigned AttrArgNum, 2320d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const Expr *IdxExpr, 2330d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko uint64_t &Idx) 2340d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko{ 2350d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko assert(isFunctionOrMethod(D) && hasFunctionProto(D)); 2360d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 2370d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko // In C++ the implicit 'this' function parameter also counts. 2380d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko // Parameters are counted from one. 2390d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const bool HasImplicitThisParam = isInstanceMethod(D); 2400d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 2410d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const unsigned FirstIdx = 1; 2420d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 2430d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko llvm::APSInt IdxInt; 2440d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2450d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { 2460d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(AttrLoc, diag::err_attribute_argument_n_not_int) 2470d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << AttrName << AttrArgNum << IdxExpr->getSourceRange(); 2480d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return false; 2490d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 2500d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 2510d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Idx = IdxInt.getLimitedValue(); 2520d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (Idx < FirstIdx || (!isFunctionOrMethodVariadic(D) && Idx > NumArgs)) { 2530d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds) 2540d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << AttrName << AttrArgNum << IdxExpr->getSourceRange(); 2550d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return false; 2560d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 2570d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Idx--; // Convert to zero-based. 2580d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (HasImplicitThisParam) { 2590d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (Idx == 0) { 2600d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(AttrLoc, 2610d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko diag::err_attribute_invalid_implicit_this_argument) 2620d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << AttrName << IdxExpr->getSourceRange(); 2630d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return false; 2640d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 2650d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko --Idx; 2660d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 2670d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 2680d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return true; 2690d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko} 2700d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 271db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// 272fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var 273fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable 274fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 27539997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) { 276fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (isa<FieldDecl>(D)) 277fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 27839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 279fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 280fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 284b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool. 285b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) { 286b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = Exp->getType(); 287b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return QT->isBooleanType() || QT->isIntegerType(); 288b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 290aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 291aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind. We assume 292aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*. 29360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 29460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins DeclContextLookupConstResult Res1 = RT->getDecl()->lookup( 29560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 29660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (Res1.first == Res1.second) 29760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return false; 29860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 29960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins DeclContextLookupConstResult Res2 = RT->getDecl()->lookup( 30060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 30160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (Res2.first == Res2.second) 30260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return false; 30360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 30460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 305aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins} 306aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 307fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type. 308fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message. 309fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise 310ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 311ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 31239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 313fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski QualType QT = vd->getType(); 31439997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (QT->isAnyPointerType()) 315fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 316aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 31760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (const RecordType *RT = QT->getAs<RecordType>()) { 31860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // If it's an incomplete type, it could be a smart pointer; skip it. 31960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // (We don't want to force template instantiation if we can avoid it, 32060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // since that would alter the order in which templates are instantiated.) 32160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (RT->isIncompleteType()) 32260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 32360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 32460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (threadSafetyCheckIsSmartPointer(S, RT)) 32560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 32660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins } 327aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 328ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 329fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName()->getName() << QT; 330fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } else { 331fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 332fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName(); 333fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 334fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 335fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 336fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points 338b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit. 3397d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) { 3407d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const RecordType *RT = QT->getAs<RecordType>()) 341b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return RT; 3427d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 3437d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer // Now check if we point to record type. 3447d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const PointerType *PT = QT->getAs<PointerType>()) 3457d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return PT->getPointeeType()->getAs<RecordType>(); 3467d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 3477d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return 0; 348b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 349b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 350bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 351fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, 352fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose CXXBasePath &Path, void *Unused) { 353bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins const RecordType *RT = Specifier->getType()->getAs<RecordType>(); 354bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (RT->getDecl()->getAttr<LockableAttr>()) 355bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return true; 356bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return false; 357bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins} 358bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 359bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType 361ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object. 36283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 36383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins QualType Ty) { 36483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins const RecordType *RT = getRecordType(Ty); 36508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 36683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins // Warn if could not get record type for this argument. 367d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT) { 368ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class) 36983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 37083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 3713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 37260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 37308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // Don't check for lockable if the class hasn't been defined yet. 374634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins if (RT->isIncompleteType()) 37583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 37660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 37760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // Allow smart pointers to be used as lockable objects. 37860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // FIXME -- Check the type that the smart pointer points to. 37960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (threadSafetyCheckIsSmartPointer(S, RT)) 38060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return; 38160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 382bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins // Check if the type is lockable. 383bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins RecordDecl *RD = RT->getDecl(); 384bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (RD->getAttr<LockableAttr>()) 38583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 386bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 387bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins // Else check if any base classes are lockable. 388bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 389bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins CXXBasePaths BPaths(false, false); 390bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths)) 391bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return; 3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 393bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 394bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 395bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski} 3973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 399ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object. 4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with. 4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function 4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list. 403ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 4043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const AttributeList &Attr, 4053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVectorImpl<Expr*> &Args, 406b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski int Sidx = 0, 407b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool ParamIdxOk = false) { 4083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 409b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski Expr *ArgExp = Attr.getArg(Idx); 4103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 411ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski if (ArgExp->isTypeDependent()) { 412ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // FIXME -- need to check this again on template instantiation 413ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski Args.push_back(ArgExp); 414ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski continue; 415ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski } 416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 41779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 4180b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins if (StrLit->getLength() == 0 || 4190b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins StrLit->getString() == StringRef("*")) { 4204e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins // Pass empty strings to the analyzer without warnings. 4210b4db3e08a201c35f0011489bd5cd5d39bbe54fbDeLesley Hutchins // Treat "*" as the universal lock. 4224e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins Args.push_back(ArgExp); 42379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins continue; 4244e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins } 42579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 426ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // We allow constant strings to be used as a placeholder for expressions 427ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // that are not valid C++ syntax, but warn that they are ignored. 428ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 429ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Attr.getName(); 4304e4c15765d5f097e21dcaa30f1a94481924340f7DeLesley Hutchins Args.push_back(ArgExp); 431ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 432ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins } 433ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins 4343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 435b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 43679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // A pointer to member expression of the form &MyClass::mu is treated 43779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // specially -- we need to look at the type of the member. 43879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 43979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UOp->getOpcode() == UO_AddrOf) 44079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 44179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DRE->getDecl()->isCXXInstanceMember()) 44279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins ArgTy = DRE->getDecl()->getType(); 44379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 4443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 4453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 446b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 4483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 4493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 451b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 452b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 4543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 4553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 4563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 457b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 459ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 460b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 4613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 462b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 463b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 46583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, ArgTy); 466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 471e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 472e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 473e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 474e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4790aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchinsenum ThreadAttributeDeclKind { 4800aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins ThreadExpectedFieldOrGlobalVar, 4810aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins ThreadExpectedFunctionOrMethod, 4820aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins ThreadExpectedClassOrStruct 4830aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins}; 4840aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins 48508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedVarAttrCommon(Sema &S, Decl *D, 486dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 488fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 489fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 490dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 492fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 493fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 4940aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 4950aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 496dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 497fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 498fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 499dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 500dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 501dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 502dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) { 503dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkGuardedVarAttrCommon(S, D, Attr)) 504fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 505fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 506dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 507fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 508fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 50908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedVarAttr(Sema &S, Decl *D, 510dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 511dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkGuardedVarAttrCommon(S, D, Attr)) 512dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 514dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!threadSafetyCheckIsPointer(S, D, Attr)) 515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 517dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 519fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 52008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkGuardedByAttrCommon(Sema &S, Decl *D, 52108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const AttributeList &Attr, 522dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr* &Arg) { 523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 525b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 526dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 5273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 5300aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 5310aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 532dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 535ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins SmallVector<Expr*, 1> Args; 536ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // check that all arguments are lockable objects 537ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 538ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins unsigned Size = Args.size(); 539ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size != 1) 540dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 542dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Arg = Args[0]; 543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 544dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 545dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 546dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 547dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) { 548dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr *Arg = 0; 549dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 550ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 551b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 552dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 55508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handlePtGuardedByAttr(Sema &S, Decl *D, 556dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 557dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr *Arg = 0; 558dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkGuardedByAttrCommon(S, D, Attr, Arg)) 559dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 560dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 561dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!threadSafetyCheckIsPointer(S, D, Attr)) 562dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 563dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 564dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 565dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han S.Context, Arg)); 566dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 56808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockableAttrCommon(Sema &S, Decl *D, 569dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 570fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 571fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 572fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 573dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 574fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 5751748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski // FIXME: Lockable structs for C code. 576fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 5770aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 5780aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedClassOrStruct; 579dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 580fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 581fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 582dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 583dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 584dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 585dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Hanstatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 586dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLockableAttrCommon(S, D, Attr)) 587dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 588dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 589dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 590dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 591dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 59208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleScopedLockableAttr(Sema &S, Decl *D, 593dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 594dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLockableAttrCommon(S, D, Attr)) 595dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 596dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 597dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 598fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 599fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 600fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 601fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 602fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 603fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 604fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 605fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 606fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 607b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 6080aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 6090aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 610fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 611fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 612fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 613768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 614fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 615fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 616fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 61771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D, 618ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 61971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany assert(!Attr.isInvalid()); 62071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 62171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!checkAttributeNumArgs(S, Attr, 0)) 62271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 62371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 62471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 62571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 62671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany << Attr.getName() << ExpectedFunctionOrMethod; 62771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 62871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany } 62971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 63071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), 631f50b6fe092091a700cee7a708d509ae7c49709f6Nick Lewycky S.Context)); 63271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany} 63371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 63408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, 63508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const AttributeList &Attr, 636dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> &Args) { 637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 638db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 639b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 640dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 643b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 644b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 6450aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 6460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFieldOrGlobalVar; 647dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 650ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that this attribute only applies to lockable types. 651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 653b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 654b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 655ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 656dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han << Attr.getName(); 657dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 658b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 661ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that all arguments are lockable objects. 662ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 663dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (Args.size() == 0) 664dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 66508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 666dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 667dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 668dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 66908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredAfterAttr(Sema &S, Decl *D, 670dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 672dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 673b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 674b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 675ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 676dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 6774ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky StartArg, Args.size())); 678dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 6793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 68008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleAcquiredBeforeAttr(Sema &S, Decl *D, 681dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 682dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> Args; 683dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkAcquireOrderAttrCommon(S, D, Attr, Args)) 684dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 685dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 686dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr **StartArg = &Args[0]; 687dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 6884ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky StartArg, Args.size())); 689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 69108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLockFunAttrCommon(Sema &S, Decl *D, 69208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const AttributeList &Attr, 693dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> &Args) { 694db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 698b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 699b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 7000aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 7010aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 702dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 703db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 706ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 707dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 708dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 709dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 710dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 71108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLockFunctionAttr(Sema &S, Decl *D, 712dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 7133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 714dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLockFunAttrCommon(S, D, Attr, Args)) 715b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 716b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 7173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 7183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 719dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 72008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 721dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han StartArg, Size)); 722dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 7233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 72408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLockFunctionAttr(Sema &S, Decl *D, 725dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 726dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> Args; 727dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLockFunAttrCommon(S, D, Attr, Args)) 728dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 729dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 730dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han unsigned Size = Args.size(); 731dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr **StartArg = Size == 0 ? 0 : &Args[0]; 732dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 73308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 734dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han StartArg, Size)); 735db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 73708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkTryLockFunAttrCommon(Sema &S, Decl *D, 73808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const AttributeList &Attr, 739dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 2> &Args) { 740db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 741db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 742b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 743dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 744b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 745b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 7460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 7470aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 748dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 751b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 752b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 753dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han << Attr.getName(); 754dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 755b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 756b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 757b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 758ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 759dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 760dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 761dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 762dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 76308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedTrylockFunctionAttr(Sema &S, Decl *D, 764dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 765dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 2> Args; 766dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 767b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 768b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 7693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 7703ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 771dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 77208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 77308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao Attr.getArg(0), 774dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han StartArg, Size)); 775dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 7763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 77708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, 778dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 779dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 2> Args; 780dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkTryLockFunAttrCommon(S, D, Attr, Args)) 781dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 782dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 783dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han unsigned Size = Args.size(); 784dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr **StartArg = Size == 0 ? 0 : &Args[0]; 785dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 78608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 78708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao Attr.getArg(0), 788dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han StartArg, Size)); 789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 79108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic bool checkLocksRequiredCommon(Sema &S, Decl *D, 79208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const AttributeList &Attr, 793dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> &Args) { 794db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 795db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 796b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 797dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 798db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 799b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 8000aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 8010aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 802dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 803db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 804db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 805b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 806ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 807dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (Args.size() == 0) 808dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return false; 80908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 810dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return true; 811dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 812dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 81308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D, 814dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 8153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 816dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLocksRequiredCommon(S, D, Attr, Args)) 817b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 818b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 819ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 820dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 82108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 82208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao StartArg, 823dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Args.size())); 824dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han} 8253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 82608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleSharedLocksRequiredAttr(Sema &S, Decl *D, 827dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han const AttributeList &Attr) { 828dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han SmallVector<Expr*, 1> Args; 829dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han if (!checkLocksRequiredCommon(S, D, Attr, Args)) 830dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han return; 831dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han 832dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Expr **StartArg = &Args[0]; 833dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 83408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Context, 83508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao StartArg, 836dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han Args.size())); 837db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 838db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 839db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 840b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 841db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 842db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 843db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 844db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 845b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 8460aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 8470aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 848db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 849db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 850db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 851b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 8523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 853ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 8543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 8553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 8563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 857768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 8583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 859db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 860db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 861db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 862b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 863db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 864db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 865b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 866db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 8673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 868db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 869b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 8700aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 8710aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 872db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 873db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 874db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 8753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 876b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 877b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 8783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 879f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins SmallVector<Expr*, 1> Args; 880f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 881f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins unsigned Size = Args.size(); 882f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins if (Size == 0) 883f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins return; 8843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 885f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, 886f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins Args[0])); 887db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 888db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 889db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 890b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 891db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 892db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 893b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 894db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 895db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 896b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 8970aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type) 8980aa52aa11e04d957f1c93c7d911e4c3dd7d5d54fDeLesley Hutchins << Attr.getName() << ThreadExpectedFunctionOrMethod; 899db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 900db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 901db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 902b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 9033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 904ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 9053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 906ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 907ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 908ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 9093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 910768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 9113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 912db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 913db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 914db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 9151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 9161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 91787c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 918545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 919803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 920545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 922bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 9249cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 9259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 9269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 9279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 9289cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 929f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 930e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 931f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 932f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 93308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 934e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, 935e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara false, false); 9364ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 9374ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 93808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 9394ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 9409cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 9419cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 9421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 9439cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 9441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 9457a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 9466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9479cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 9489cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 9499cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 9509ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 9519cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 952ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 953a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 954bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 9569cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 9576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 9621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 9636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 964bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 96587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 966768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 96787c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 9686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 9696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 9706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 971803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 972fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 97308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 9746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 975768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 9766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 9773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 98187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 983c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 984c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 985c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 986c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 9871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 98896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 9891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 99096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 991bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 99263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 99387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 99463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 995768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 99663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 99763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 99863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 9994ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 100063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 100163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 10022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 10032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // The IBOutlet/IBOutletCollection attributes only apply to instance 10042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // variables or properties of Objective-C classes. The outlet must also 10052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // have an object reference type. 10062f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 10072f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 10080bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 10092f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << VD->getType() << 0; 10102f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 10112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 10122f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 10132f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 10142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 1015f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 10162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << PD->getType() << 1; 10172f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 10182f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 10192f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 10202f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else { 10212f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 10222f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 10232f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 1024f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 10252f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return true; 10262f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek} 10272f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 10281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 102963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 10301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 103163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 103208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 10332f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 103463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 103563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 10362f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 103796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 103896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 10391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 10401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1041857e918a8a40deb128840308a318bf623d68295fTed Kremenek 1042857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 1043a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 1044857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1045857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 1046857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 1047857e918a8a40deb128840308a318bf623d68295fTed Kremenek 10482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 1049857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 10502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 1051a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 1052a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 1053f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian II = &S.Context.Idents.get("NSObject"); 105408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 105508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 105687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 1057a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 1058a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 1059a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 1060a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 1061b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 1062a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 1063a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 1064a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 1065a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 1066f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 1067a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 1068a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 1069a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 1070f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 1071f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis QT, Attr.getParameterLoc())); 1072857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 1073857e918a8a40deb128840308a318bf623d68295fTed Kremenek 1074d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 107568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 107668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 107768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 107868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 107968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 108068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 108168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 108268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 108368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 108468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 108568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 108668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 108768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 108868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 1089587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopesstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1090174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes if (!isFunctionOrMethod(D)) { 1091174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1092174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes << "alloc_size" << ExpectedFunctionOrMethod; 1093174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes return; 1094174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes } 1095174930db339bb7213353db9e7b5aa94ecf4c12eaNuno Lopes 1096587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 1097587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 1098587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1099587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // In C++ the implicit 'this' function parameter also counts, and they are 1100587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // counted from one. 1101587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes bool HasImplicitThisParam = isInstanceMethod(D); 1102587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1103587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1104587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes SmallVector<unsigned, 8> SizeArgs; 1105587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1106587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes for (AttributeList::arg_iterator I = Attr.arg_begin(), 1107587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes E = Attr.arg_end(); I!=E; ++I) { 1108587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // The argument must be an integer constant expression. 1109587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes Expr *Ex = *I; 1110587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes llvm::APSInt ArgNum; 1111587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (Ex->isTypeDependent() || Ex->isValueDependent() || 1112587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 1113587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1114587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 1115587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 1116587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1117587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1118587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes uint64_t x = ArgNum.getZExtValue(); 1119587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1120587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (x < 1 || x > NumArgs) { 1121587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 1122587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << I.getArgNum() << Ex->getSourceRange(); 1123587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 1124587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1125587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1126587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes --x; 1127587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (HasImplicitThisParam) { 1128587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (x == 0) { 1129587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), 1130587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes diag::err_attribute_invalid_implicit_this_argument) 1131587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 1132587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 1133587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1134587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes --x; 1135587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1136587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1137587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // check if the function argument is of an integer type 1138587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 1139587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!T->isIntegerType()) { 1140587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1141587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 1142587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 1143587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1144587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1145587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes SizeArgs.push_back(x); 1146587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1147587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 1148587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // check if the function returns a pointer 1149587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!getFunctionType(D)->getResultType()->isAnyPointerType()) { 1150587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 1151587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange(); 1152587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 1153587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 115496c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context, 115596c67d1c2aff532729c9edb297617094d1e77cc1Nuno Lopes SizeArgs.data(), SizeArgs.size())); 1156587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes} 1157587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 11581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1159bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 1160bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 116187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 1162fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1163883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1164eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1165eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 116707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 116807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 116987c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 117087c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1171eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 1172eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 11735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 1174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1175eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 1176eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 1177bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1179eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 11807a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 1181eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 1182ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 1183ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 1184fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1185fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 1186eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1187eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1188bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1189eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1191eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 1192fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 119330bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 1194eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1195eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1197465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 119807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 119907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 120007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 120107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 120207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 120307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 120407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 120507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 120607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 1207eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 1208eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 120987c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 1210d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 121108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1212dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1213eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 1214c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 1215fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 12167fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 1217eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1219eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 1220eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 12247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 122587c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 122687c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 1227d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 1228dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 1229d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 123046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 1231bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1232ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 123360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 123460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 123560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 123660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 123760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 12387fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 123960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 1240eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 12417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 12427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 12437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 1244dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1245768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 1246cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 1247eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 1248eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 12491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 1250dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 1251dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 1252dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 1253dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 1254dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 1255dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 12562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 12572a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 1258dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1259dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 1260dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 1261dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 1262dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1263dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1264dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 1265cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 12662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 12672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 1268cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 1269dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 1270dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1271dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1272dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 12732a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 12742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 1275cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 1276dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 1277dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1278dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1279dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 12802a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 12812a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 1282cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 1283dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1284dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 1285dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 1286dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1287dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 12882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 12892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 12902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 12912a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 1292dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1293dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 129487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 1295883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 1296883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 1297dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1298dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1299dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 130007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 130107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 130287c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 130387c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1304dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 13055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 1306dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1307dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 1308dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 1309dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 1310dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 13115f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 1312dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 13132a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 13142a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 1315dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 13167a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 1317dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1318dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1319dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1320dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1321dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1322dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1323dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1324dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1325dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1326dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1327dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1328dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1329dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1330dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1331dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1332dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 133307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 133407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 133507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 133607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 133707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 133807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 133907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 134007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 134107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1342dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1343cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1344cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1345dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 134687c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1347dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1348dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1349dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1350cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1351dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1352dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1353dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1354dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1355dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1356dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1357cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1358dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1359dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 13607a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1361dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1362dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1363dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1364dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1365dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1366dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1367dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1368dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1369dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1370dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1371dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1372dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1373dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1374dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1375cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 137687c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 137787c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1378cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1379cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1380cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1381cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1382cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1383cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1384cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1385dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1386dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1387dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1388dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1389dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1390dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1391dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1392dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1393dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1394dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1395cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1396cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1397cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1398cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1399dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1400cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 140187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1402cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1403dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1404dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1405332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1406332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1407332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1408332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1409332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1410332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1411332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1412332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1413332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1414332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1415332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1416332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1417332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1418332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1419332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1420332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1421332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 142211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 142311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 14241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 142511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 142611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 142711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 142811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 142911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 143011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 143187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1432332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1433883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1434332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1435332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1436332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 143787c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1438332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 143911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 144011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 144111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 144211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 144311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 144411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 144511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 144611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 144711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 144811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 144987c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 14507a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 14517a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1452332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 14537a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 145411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 145511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 145611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 145711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 145811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 145911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 146011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 146111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 146211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 146311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 146411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 146511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 146611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 146711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 146811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 146911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 147011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 147111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 147211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 147311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1474332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1475332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 147611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 147711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 147811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 147911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 148011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 148111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 148211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 148311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 14847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 148511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 148611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 148711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 14885cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 148911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 149011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 149111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 149211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 149311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 149411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 1495768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1496f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 149711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 149811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 150011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 150111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 15021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 15036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1504545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 15053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 15066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15097a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 15106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 15116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1512bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 15135cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1514fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 15153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 15166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 15176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1518bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1519bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1520f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1521f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1522f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1523f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 15246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1525bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1526768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1527f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 15286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1530ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1531ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer // Check the attribute arguments. 1532ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!checkAttributeNumArgs(S, Attr, 0)) 1533ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1534ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1535ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!isa<FunctionDecl>(D)) { 1536ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1537ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << ExpectedFunction; 1538ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1539ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1540ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1541ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (D->hasAttr<HotAttr>()) { 1542ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1543ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << "hot"; 1544ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1545ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1546ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1547ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context)); 1548ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer} 1549ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1550ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1551ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer // Check the attribute arguments. 1552ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!checkAttributeNumArgs(S, Attr, 0)) 1553ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1554ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1555ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!isa<FunctionDecl>(D)) { 1556ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1557ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << ExpectedFunction; 1558ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1559ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1560ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1561ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (D->hasAttr<ColdAttr>()) { 1562ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1563ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << "cold"; 1564ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1565ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1566ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1567ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context)); 1568ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer} 1569ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 15701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1571dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 15721731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1573dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1574dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 157587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1576dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1577883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1578dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1579dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1580dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 1581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1582dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1583dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 15841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 15851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1586dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1587831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 15883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1589af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1590af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 15915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 159287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 15935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1594883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 15955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 15965bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1597bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1599af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1600af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 16015e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborgstatic void handleTLSModelAttr(Sema &S, Decl *D, 16025e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg const AttributeList &Attr) { 16035e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg // Check the attribute arguments. 16045e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg if (Attr.getNumArgs() != 1) { 16055e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 16065e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg return; 16075e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg } 16085e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16095e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg Expr *Arg = Attr.getArg(0); 16105e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg Arg = Arg->IgnoreParenCasts(); 16115e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 16125e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16135e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg // Check that it is a string. 16145e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg if (!Str) { 16155e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg S.Diag(Attr.getLoc(), diag::err_attribute_not_string) << "tls_model"; 16165e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg return; 16175e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg } 16185e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16195e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) { 16205e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 16215e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg << Attr.getName() << ExpectedTLSVar; 16225e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg return; 16235e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg } 16245e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16255e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg // Check that the value. 16265e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg StringRef Model = Str->getString(); 16275e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg if (Model != "global-dynamic" && Model != "local-dynamic" 16285e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg && Model != "initial-exec" && Model != "local-exec") { 16295e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg S.Diag(Attr.getLoc(), diag::err_attr_tlsmodel_arg); 16305e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg return; 16315e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg } 16325e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16335e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context, 16345e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg Model)); 16355e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg} 16365e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg 16371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1638dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1639831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 164076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 164176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 164276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 16431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 164487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 16451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 16462cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1647768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 16482cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 16492cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1650fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1651fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 16522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 165376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 165476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 16551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 165634c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 16571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 165834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 165934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 1660768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 166134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 166234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 16631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 166456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 166587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1667722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1668722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1669883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1670a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1671a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 16721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 167356aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 167487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1675768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1676722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1677722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1678883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1679a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1680a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 16811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 168287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1683711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1684711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1685711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 168687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1687711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1688883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1689711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1690711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1691711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1692768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1693711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1694711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1695711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1696831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1697711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1698711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1699711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1700711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1701711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1702711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1703b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1704b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 17051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 17061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 170708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1708b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1709b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 171008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 17111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 17121731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 171308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 171487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 171587c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 17163ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 17173ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1718e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1719e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1720b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1721883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1722b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 172319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 17246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 172508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1726768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 17276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 17286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 172935cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 17301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 173135cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 173235cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 173308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 173408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao According to the PPU ABI specifications, a class with a single member of 1735f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1736f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1737f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1738f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 173908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 174035cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 174108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 174235cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 174335cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 174435cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 174535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 174608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 174735cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 174835cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 174935cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 175035cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 175135cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 175235cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 175335cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 175487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 175535cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1756883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 175735cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 175835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 175935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 176087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 176135cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 176235cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 176335cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 176435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 176587c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 176601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 176701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 176801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 176901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 177001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 177101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 177201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 177301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 177401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 177501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 177601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 177701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1778f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1779f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 178001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 178101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 178201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 178301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 178401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 178501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 178601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1787768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 178835cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 178935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 179187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1792bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1793883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1794bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1795bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1796bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1797bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1798bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 17991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 180073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1801831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 18023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 180373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 180473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1805bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 180687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 1807568eae48a4e19c0359cdcd2a33b8ec9812e4abbcDaniel Jasper !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) { 1808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1809883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 181073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 181173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1812bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1813768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 181473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 181573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 1816f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D, 1817f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola const AttributeList &Attr) { 1818f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola // check the attribute arguments. 1819f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (Attr.hasParameterOrArguments()) { 1820f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1821f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1822f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1823f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1824f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (!isa<FunctionDecl>(D)) { 1825f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1826f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola << Attr.getName() << ExpectedFunction; 1827f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1828f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1829f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1830f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1831f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola} 1832f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 18331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1834b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1835831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1836b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1837b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1838b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1839bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 184087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1841186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1842b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1843b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1844b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 184587c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1846b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1847883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1848b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1849b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1850bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1851768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1852b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1853b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 18541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 18553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1856bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1857bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 18583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1859bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 18603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 18613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 18623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 18637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 18643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1865ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1866ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 18693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 18703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 18713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 18723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 187487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1876883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 18773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 18783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 18793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1880768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1881f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 18823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 18833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 18841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 18853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1886bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1887bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 18883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 18903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 18913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 18923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 18937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 18943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1895ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1896ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 18993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 19003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 19013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 19023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1903bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 190487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1905fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1906883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 19073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 19083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 19093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1910768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1911f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 19123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 19133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1914bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramertemplate <typename AttrTy> 1915bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramerstatic void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr, 1916bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer const char *Name) { 1917951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1918951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1919bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1920c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1921c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1922bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer 1923bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer // Handle the case where the attribute has a text message. 19245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1925951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1926951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1927c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1928951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1929bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer << Name; 1930c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1931c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1932951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 19336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1934bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1935bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str)); 1936bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1937bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 193808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1939742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1940742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1941742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1942742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1943742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1944742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 194508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1946742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1947768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis Attr.getRange(), S.Context)); 1948742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1949742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 195008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRootClassAttr(Sema &S, Decl *D, 1951b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard const AttributeList &Attr) { 1952b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!isa<ObjCInterfaceDecl>(D)) { 1953b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1954b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1955b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 195608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1957b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard unsigned NumArgs = Attr.getNumArgs(); 1958b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NumArgs > 0) { 1959b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1960b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1961b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 196208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1963b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); 1964b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard} 1965b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 196608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaostatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 1967e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian const AttributeList &Attr) { 1968341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian if (!isa<ObjCInterfaceDecl>(D)) { 1969341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 1970341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian return; 1971341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian } 197208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 1973e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1974e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian if (NumArgs > 0) { 1975e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1976e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian return; 1977e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian } 197808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 197971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( 1980e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian Attr.getRange(), S.Context)); 1981e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian} 1982e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 1983fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkAvailabilityAttr(Sema &S, SourceRange Range, 1984fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose IdentifierInfo *Platform, 1985fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Introduced, 1986fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Deprecated, 1987fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Obsoleted) { 19885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 19890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 19903b294360febd89e3383143af086efe2014571afaRafael Espindola if (PlatformName.empty()) 19910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 19920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1993c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 19940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 19953b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Introduced.empty() && !Deprecated.empty() && 19963b294360febd89e3383143af086efe2014571afaRafael Espindola !(Introduced <= Deprecated)) { 19973b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 19983b294360febd89e3383143af086efe2014571afaRafael Espindola << 1 << PlatformName << Deprecated.getAsString() 19993b294360febd89e3383143af086efe2014571afaRafael Espindola << 0 << Introduced.getAsString(); 20003b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 20010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 20020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 20033b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Introduced.empty() && !Obsoleted.empty() && 20043b294360febd89e3383143af086efe2014571afaRafael Espindola !(Introduced <= Obsoleted)) { 20053b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 20063b294360febd89e3383143af086efe2014571afaRafael Espindola << 2 << PlatformName << Obsoleted.getAsString() 20073b294360febd89e3383143af086efe2014571afaRafael Espindola << 0 << Introduced.getAsString(); 20083b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 20090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 20100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 20113b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Deprecated.empty() && !Obsoleted.empty() && 20123b294360febd89e3383143af086efe2014571afaRafael Espindola !(Deprecated <= Obsoleted)) { 20133b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 20143b294360febd89e3383143af086efe2014571afaRafael Espindola << 2 << PlatformName << Obsoleted.getAsString() 20153b294360febd89e3383143af086efe2014571afaRafael Espindola << 1 << Deprecated.getAsString(); 20163b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 20173b294360febd89e3383143af086efe2014571afaRafael Espindola } 20183b294360febd89e3383143af086efe2014571afaRafael Espindola 20193b294360febd89e3383143af086efe2014571afaRafael Espindola return false; 20203b294360febd89e3383143af086efe2014571afaRafael Espindola} 20213b294360febd89e3383143af086efe2014571afaRafael Espindola 2022599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaAvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range, 2023599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola IdentifierInfo *Platform, 2024599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Introduced, 2025599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Deprecated, 2026599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Obsoleted, 2027599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola bool IsUnavailable, 2028599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola StringRef Message) { 202998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedIntroduced = Introduced; 203098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedDeprecated = Deprecated; 203198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedObsoleted = Obsoleted; 20323b294360febd89e3383143af086efe2014571afaRafael Espindola bool FoundAny = false; 20333b294360febd89e3383143af086efe2014571afaRafael Espindola 203498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (D->hasAttrs()) { 203598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola AttrVec &Attrs = D->getAttrs(); 203698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola for (unsigned i = 0, e = Attrs.size(); i != e;) { 203798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 203898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (!OldAA) { 203998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 204098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 204198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 204298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 204398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola IdentifierInfo *OldPlatform = OldAA->getPlatform(); 204498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (OldPlatform != Platform) { 204598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 204698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 204798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 204898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 204998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola FoundAny = true; 205098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldIntroduced = OldAA->getIntroduced(); 205198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldDeprecated = OldAA->getDeprecated(); 205298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldObsoleted = OldAA->getObsoleted(); 205398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola bool OldIsUnavailable = OldAA->getUnavailable(); 205498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola StringRef OldMessage = OldAA->getMessage(); 205598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 205698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if ((!OldIntroduced.empty() && !Introduced.empty() && 205798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldIntroduced != Introduced) || 205898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (!OldDeprecated.empty() && !Deprecated.empty() && 205998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldDeprecated != Deprecated) || 206098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (!OldObsoleted.empty() && !Obsoleted.empty() && 206198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldObsoleted != Obsoleted) || 206298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (OldIsUnavailable != IsUnavailable) || 206398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (OldMessage != Message)) { 206498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 206598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 206698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Attrs.erase(Attrs.begin() + i); 206798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola --e; 206898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 206998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 207098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 207198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedIntroduced2 = MergedIntroduced; 207298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedDeprecated2 = MergedDeprecated; 207398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedObsoleted2 = MergedObsoleted; 207498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 207598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedIntroduced2.empty()) 207698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced2 = OldIntroduced; 207798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedDeprecated2.empty()) 207898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedDeprecated2 = OldDeprecated; 207998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedObsoleted2.empty()) 208098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted2 = OldObsoleted; 208198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 208298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 208398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced2, MergedDeprecated2, 208498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted2)) { 208598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Attrs.erase(Attrs.begin() + i); 208698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola --e; 208798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 208898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 208998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 209098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced = MergedIntroduced2; 209198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedDeprecated = MergedDeprecated2; 209298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted = MergedObsoleted2; 209398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 209498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 20950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 20960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 20973b294360febd89e3383143af086efe2014571afaRafael Espindola if (FoundAny && 20983b294360febd89e3383143af086efe2014571afaRafael Espindola MergedIntroduced == Introduced && 20993b294360febd89e3383143af086efe2014571afaRafael Espindola MergedDeprecated == Deprecated && 21003b294360febd89e3383143af086efe2014571afaRafael Espindola MergedObsoleted == Obsoleted) 2101599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 21023b294360febd89e3383143af086efe2014571afaRafael Espindola 210398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 21043b294360febd89e3383143af086efe2014571afaRafael Espindola MergedDeprecated, MergedObsoleted)) { 2105599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) AvailabilityAttr(Range, Context, Platform, 2106599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Introduced, Deprecated, 2107599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Obsoleted, IsUnavailable, Message); 21080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 2109599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 21103b294360febd89e3383143af086efe2014571afaRafael Espindola} 21110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 21123b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D, 21133b294360febd89e3383143af086efe2014571afaRafael Espindola const AttributeList &Attr) { 21143b294360febd89e3383143af086efe2014571afaRafael Espindola IdentifierInfo *Platform = Attr.getParameterName(); 21153b294360febd89e3383143af086efe2014571afaRafael Espindola SourceLocation PlatformLoc = Attr.getParameterLoc(); 21163b294360febd89e3383143af086efe2014571afaRafael Espindola 21173b294360febd89e3383143af086efe2014571afaRafael Espindola if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty()) 21183b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 21193b294360febd89e3383143af086efe2014571afaRafael Espindola << Platform; 21200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 21213b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 21223b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 21233b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 21243b294360febd89e3383143af086efe2014571afaRafael Espindola bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 2125006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian StringRef Str; 212608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao const StringLiteral *SE = 2127006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); 2128006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian if (SE) 2129006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str = SE->getString(); 21303b294360febd89e3383143af086efe2014571afaRafael Espindola 2131599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(), 2132599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Platform, 2133599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Introduced.Version, 2134599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Deprecated.Version, 2135599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Obsoleted.Version, 2136599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola IsUnavailable, Str); 2137599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2138599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 213998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola} 214098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 2141599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 2142599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VisibilityAttr::VisibilityType Vis) { 2143dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola if (isa<TypedefNameDecl>(D)) { 2144dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility"; 2145599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2146dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola } 214798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>(); 214898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (ExistingAttr) { 214998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility(); 215098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (ExistingVis == Vis) 2151599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 215298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility); 215398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 215498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola D->dropAttr<VisibilityAttr>(); 215598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 2156599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) VisibilityAttr(Range, Context, Vis); 21570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 21580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 21591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 21606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 21611731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 21626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 21656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 21666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 2167bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21685cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 2169fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 21703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 21716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 21726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 2175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 2176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2177c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 2178cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 2179c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 2180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 2181c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 2182cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 21834188760f6bb20f91c6883dffd89204419f852deeJohn McCall else if (TypeStr == "protected") { 21844188760f6bb20f91c6883dffd89204419f852deeJohn McCall // Complain about attempts to use protected visibility on targets 21854188760f6bb20f91c6883dffd89204419f852deeJohn McCall // (like Darwin) that don't support it. 21864188760f6bb20f91c6883dffd89204419f852deeJohn McCall if (!S.Context.getTargetInfo().hasProtectedVisibility()) { 21874188760f6bb20f91c6883dffd89204419f852deeJohn McCall S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 21884188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Default; 21894188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 21904188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Protected; 21914188760f6bb20f91c6883dffd89204419f852deeJohn McCall } 21924188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 219308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 21946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 21956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2197599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type); 2198599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2199599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 22006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 22016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 22031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 2204d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 2205d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 220687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 2207883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 2208d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2209d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2210d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 221187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 221287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 221387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2214d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 2215d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 221687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2217d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 221887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2219d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2220d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2221d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 22225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 2223d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 2224d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 2225d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 2226d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 2227d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 2228d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 2229d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 2230d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 2231d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 2232d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 2233d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 2234d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 2235d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 2236d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 2237d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 2238d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 223987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 2240d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2241d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2242d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 224308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao if (family == ObjCMethodFamilyAttr::OMF_init && 2244f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 2245f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 2246f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 2247f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 2248f85e193739c953358c865005855253af4f68a497John McCall return; 2249f85e193739c953358c865005855253af4f68a497John McCall } 2250f85e193739c953358c865005855253af4f68a497John McCall 2251768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 2252f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 2253d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 2254d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 22551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 22561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 22571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 22580db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 2259bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22600db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 22610db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 22620db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 22630db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 22640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 2265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2266768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 22670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 22680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 22691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 2270fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 22712b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2272fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 2273fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 2274162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2275fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 22769af9122067f1334806a5f22ce907a3209490d506Ted Kremenek if (!T->isCARCBridgableType()) { 2277fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 2278fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 2279fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 2280fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 22813427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 22823427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian QualType T = PD->getType(); 22839af9122067f1334806a5f22ce907a3209490d506Ted Kremenek if (!T->isCARCBridgableType()) { 22843427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian S.Diag(PD->getLocation(), diag::err_nsobject_attribute); 22853427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian return; 22863427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian } 22873427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian } 22883427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian else { 2289f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // It is okay to include this attribute on properties, e.g.: 2290f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 2291f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 2292f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 2293f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // In this case it follows tradition and suppresses an error in the above 229408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // case. 22959b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 2296f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek } 2297768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 2298fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 2299fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 2300bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 23011b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2302f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 23032b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2304f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 2305f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 2306f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 2307f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 2308f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 2309f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 2310f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 2311f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 2312768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 2313f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 2314f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 23151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 23183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 23199eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 23209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2321bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23229eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 23233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 23249eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 23259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2326bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2327cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 232892e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 23299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 23309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 2331fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 23323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 23339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 23349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2336768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 23379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 23389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 23391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2340770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 2341770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 2342bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 2343770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2344bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2345bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23463323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned sentinel = 0; 2347770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 23487a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 2349770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 2350ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2351ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 2352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 2354770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2355770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2356bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23573323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if (Idx.isSigned() && Idx.isNegative()) { 2358fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 2359fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 2360770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2361770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 23623323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall 23633323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall sentinel = Idx.getZExtValue(); 2364770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2365770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 23663323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned nullPos = 0; 2367770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 23687a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 2369770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 2370ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2371ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 2372fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 2374770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2375770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2376770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 2377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23783323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 2379770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 2380770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 2381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 2382fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 2383770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2384770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2385770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2386770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 238787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 23883323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 2389897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 2390897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 2391897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 2392897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 2393bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2394897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 23953bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2396770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2397bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 239887c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2399770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 24003bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2401770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 24022f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2403a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 2404a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman if (!BD->isVariadic()) { 2405a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 2406a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman return; 2407a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } 240887c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 24092f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 2410daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 241187c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 2412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 24132f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 24143bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 24153bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 24162f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 24172f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2418ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 24192f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2420883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 24212f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 24222f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2423770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 2424fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2425883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 2426770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2427770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2428768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 2429f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 2430770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 2431770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 24321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 2433026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 24341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2435026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 2436026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 2437f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 2438026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2439883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 2440026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 2441026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 2442bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2443f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 2444f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2445f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 2446f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 2447f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 2448f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 2449f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 2450f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2451f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 2452f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 2453f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 245408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 2455768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 2456026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 2457026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 24581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 24596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 246087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 246187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 246587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 246613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian if (isa<CXXRecordDecl>(D)) { 246713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 246813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian return; 246913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian } 247087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 247187c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 2472f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 2473f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 2474f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 247587c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 2476332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 2477332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 2478332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 247987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 24806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 24816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 2482bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2483768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 24846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 24876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 24881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 24896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 24901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 24916e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 24926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 24936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 24940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 24950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 24960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 24970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 24980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 2499def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2500bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 250190eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2502def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 2503def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 2504c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2505883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 25066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 25076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 25086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 25096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 2510768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 25116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 25126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 25130df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner// Handles reqd_work_group_size and work_group_size_hint. 25140df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattnerstatic void handleWorkGroupSize(Sema &S, Decl *D, 25154ae89bc757f16baeb74ebeea81c43dc5201cb4f2Nick Lewycky const AttributeList &Attr) { 251608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao assert(Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize 25170df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner || Attr.getKind() == AttributeList::AT_WorkGroupSizeHint); 25180df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner 25196f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 25200df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (!checkAttributeNumArgs(S, Attr, 3)) return; 25216f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 25226f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 25236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 25247a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 25256f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 2526ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2527ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 25286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 25290df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner << Attr.getName()->getName() << E->getSourceRange(); 25306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 25316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 25326f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 25336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 25340df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner 25350df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize 25360df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner && D->hasAttr<ReqdWorkGroupSizeAttr>()) { 25370df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>(); 25380df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (!(A->getXDim() == WGSize[0] && 25390df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner A->getYDim() == WGSize[1] && 25400df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner A->getZDim() == WGSize[2])) { 25410df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << 25420df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner Attr.getName(); 25430df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner } 25440df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner } 25450df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner 25460df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint 25470df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner && D->hasAttr<WorkGroupSizeHintAttr>()) { 25480df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>(); 25490df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (!(A->getXDim() == WGSize[0] && 25500df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner A->getYDim() == WGSize[1] && 25510df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner A->getZDim() == WGSize[2])) { 25520df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << 25530df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner Attr.getName(); 25540df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner } 25550df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner } 25560df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner 25570df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize) 25580df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner D->addAttr(::new (S.Context) 25590df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 25600df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner WGSize[0], WGSize[1], WGSize[2])); 25610df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner else 25620df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner D->addAttr(::new (S.Context) 25630df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner WorkGroupSizeHintAttr(Attr.getRange(), S.Context, 25640df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner WGSize[0], WGSize[1], WGSize[2])); 25656f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 25666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2567599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 2568599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola StringRef Name) { 2569420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 2570420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola if (ExistingAttr->getName() == Name) 2571599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2572420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 2573420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 2574599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2575420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola } 2576599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) SectionAttr(Range, Context, Name); 25776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 25786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 25791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 258017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 25811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 258217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 258317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 258417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 258517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 25867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2587797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 258817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 2589797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 259017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 259117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 25921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2593797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 2594bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2595a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 2596a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2597a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 2598797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 2599797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 26001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2601a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 2602a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2603a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2604a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 2605a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 2606599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), 2607599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola SE->getString()); 2608599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2609599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 261017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 261117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 26126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 26146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2615831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 26163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 26176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 261908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 262087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2621b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2622ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2623b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2624768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2625b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 26266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 26276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2629232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2630831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 26313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2632232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2633232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2634bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 263587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2636b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2637ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2638b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2639768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2640b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2641232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2642232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 26431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2644232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 26451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2646232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2648768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2649232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2650232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 26511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2653f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2654f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2655f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2657f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2658f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2659f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2660f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 266287c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2664f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2665f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2666f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2667f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2668bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2669f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2670c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2671f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2672f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2673f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2674f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2675f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2676f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2677f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2678f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2680f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2681f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2682f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2683f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2684f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2685f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2686f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2687f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2688f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2689f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2690f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2691f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2692f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2693f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2694bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 269589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 269689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 269789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 269889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2699b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2700b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2701f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 270289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 270389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 270489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 270589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2707768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 27085f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); 2709f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2710f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2711bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 27131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 27141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 27155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 27161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 271787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 27185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2719883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 27205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 27215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 272207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 272307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 272407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 272587c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 272687c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 27275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 272807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 27295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 27307a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 27315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2732ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2733ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 27345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 27355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 27365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 27375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2738bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 27405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 27415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 27425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 27435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 274707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 274807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 274907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 275007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 275107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 275207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 275307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 275407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 275507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 27565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 275787c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 27605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 27615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 27625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 27636217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 27645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 27655b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2766bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 27675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 27685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 277087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 27715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 27725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 27735b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 27746217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 27755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 27765b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2777bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 27785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 27795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2780bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2781bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2782768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 278307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 27845b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 27855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 27862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 27872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 27882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 27892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 27902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 27913c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 27922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 27932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 27942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 27952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 27962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 27975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 2798c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer return llvm::StringSwitch<FormatAttrKind>(Format) 2799c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer // Check for formats that get handled specially. 2800c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("NSString", NSStringFormat) 2801c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("CFString", CFStringFormat) 2802c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("strftime", StrftimeFormat) 2803c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer 2804c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer // Otherwise, check for supported formats. 2805c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 2806c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 2807c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("kprintf", SupportedFormat) // OpenBSD. 2808c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer 2809c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 2810c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Default(InvalidFormat); 28112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 28122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2813521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2814521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 28151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 28161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 28174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus) { 2818521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2819521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2820521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 282108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 282287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2823b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2824b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2825b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2826b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 282787c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2828b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2829b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2830b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2831b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2832b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2833b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2834b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 283508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 2836521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2837521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2838521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2839521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2840521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 28417a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 284208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 2843521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2844521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2845521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2846521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2847521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2848521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2849521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2850521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 28519f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2852521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2853521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2854521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2855521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2856521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2857521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2859f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2860521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2861521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2862599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, 2863599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola int FormatIdx, int FirstArg) { 2864bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // Check whether we already have an equivalent format attribute. 2865bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola for (specific_attr_iterator<FormatAttr> 2866bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola i = D->specific_attr_begin<FormatAttr>(), 2867bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola e = D->specific_attr_end<FormatAttr>(); 2868bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola i != e ; ++i) { 2869bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola FormatAttr *f = *i; 2870bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola if (f->getType() == Format && 2871bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->getFormatIdx() == FormatIdx && 2872bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->getFirstArg() == FirstArg) { 2873bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // If we don't have a valid location for this attribute, adopt the 2874bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // location. 2875bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola if (f->getLocation().isInvalid()) 2876bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->setRange(Range); 2877599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2878bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola } 2879bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola } 2880bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola 2881599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 2882599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FirstArg); 2883bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola} 2884bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola 2885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 28871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 28886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2889545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2890fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 28913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 28926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 28946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2895545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 28963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 28976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 28996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 290087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2902883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 29036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 290607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 290707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 290987c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 29106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 29116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 29136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 29152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 29162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 29172b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 29182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 29192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 292008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 29213c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 29223c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 292308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 29242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2925fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 292601eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 29276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 29317a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2932803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2933ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2934ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2935fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 29363c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 29376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2941fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 29423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 29436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 29476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2948bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29494a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 29504a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 295107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 295207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 295307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 29544a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 29554a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 29564a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 29574a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 29581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 296087c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 29616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2963085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2964fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2965fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2966085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2967085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 29682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2969390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2970390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2971803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2972390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2973fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2974fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 29756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2976bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 29776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 29786217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2979390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2980fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2981fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 29826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 29867a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2987803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2988ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2989ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2990fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 29913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 29926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 29946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 29966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 299787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 29986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 29996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 300087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 30016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 30036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 30046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 30063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 30072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 30086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 3009fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 3010fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 30116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 30136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 30146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 3015fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 30163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 30176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 30196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3020599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format, 3021cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 3022599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FirstArg.getZExtValue()); 3023599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 3024599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 30256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 30266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 30281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 30296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 30301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 30316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 30336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 30350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 303687c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 30370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 30380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 30390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 304087c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 30410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 30420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 3043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3044883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 30456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 30476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30485e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall if (!RD->isCompleteDefinition()) { 3049bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 30500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 30510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 30520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 30530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 305417945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 305517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 30560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 30570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 30580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 30590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 3060bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 30610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 30620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 306390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 3064bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 306590cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 306690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 30670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 30680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 3069bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 30700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 30710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 30720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 30730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 30740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 30750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 30760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 30770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 3078bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 30790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 3080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 30810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 30820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 30830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 3084bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 30850c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 30860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 3087bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 3088bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 3089bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 30906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3091768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 30926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 30936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 30956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 30961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 30976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 30981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 30997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 3100797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 3101bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 31026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 31036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 31046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 3105797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 31066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 31076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 310877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 310977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Don't duplicate annotations that are already set. 311077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge for (specific_attr_iterator<AnnotateAttr> 311177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge i = D->specific_attr_begin<AnnotateAttr>(), 311277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 311377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge if ((*i)->getAnnotation() == SE->getString()) 311477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return; 311577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 3116768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 3117f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 31186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 31196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 31201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 31216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 3122545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 31233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 31246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 31256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3126fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman 3127bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 3128bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 3129bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 31306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3131545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 313208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 3133fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman true, 0, Attr.isDeclspecAttribute())); 31344ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 31354ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 31364ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 313708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0), 3138fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman Attr.isDeclspecAttribute()); 31394ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 31404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 314108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 3142fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman bool isDeclSpec) { 31430b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne // FIXME: Handle pack-expansions here. 31440b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne if (DiagnoseUnexpandedParameterPack(E)) 31450b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne return; 31460b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne 31474ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 31484ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 314908fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E, 3150fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman isDeclSpec)); 31516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 31526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3154768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis SourceLocation AttrLoc = AttrRange.getBegin(); 3155cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 315649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 3157ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor ExprResult ICE 3158ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor = VerifyIntegerConstantExpression(E, &Alignment, 3159ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor diag::err_aligned_attribute_argument_not_int, 3160ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor /*AllowFold*/ false); 3161282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith if (ICE.isInvalid()) 316249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 3163396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 31644ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 31654ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 3166396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 3167396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 3168fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman if (isDeclSpec) { 3169fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman // We've already verified it's a power of 2, now let's make sure it's 3170fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman // 8192 or less. 3171fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman if (Alignment.getZExtValue() > 8192) { 317208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192) 3173fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman << E->getSourceRange(); 3174fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman return; 3175fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman } 3176fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman } 3177396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 317808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(), 3179fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman isDeclSpec)); 3180cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 3181cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 318208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liaovoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 3183fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman bool isDeclSpec) { 3184cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 3185cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 318608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS, 3187fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman isDeclSpec)); 3188cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 31896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3191d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 3192bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 3193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 3194bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 3195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 3196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 31971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 3199fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 3200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 32021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 32041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 3207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 32080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 3209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3211210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 32125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 3213fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 3215210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 3216210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 3217fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 3219fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 322073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 3221210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 3222fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 322373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 322473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 322573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 322673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 322773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 322873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 322973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 323073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 323173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 323273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 323373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 323473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 323573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 323673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 323773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 323873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 3241fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 3242fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 3243210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 3244bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3245210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 3246bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 3247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 3249210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 3250bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3253fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 3255162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 3257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3258fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 3259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 3260fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 3261768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << "mode" << Attr.getRange(); 3262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 326473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 3265183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 326673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 326773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 32682ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 326973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 327073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 327173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 327273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 327373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 327473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 327573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 327673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 327773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 3278390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 3279390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 3280390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 3281390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 3282f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 3283f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 3284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 3285fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 3286fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 32873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 3288fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3289fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 32903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 3291fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 329373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 329473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 329573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 329673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3297fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 32980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 3299fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 33000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 3301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 330373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 330473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 330573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 330673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3307fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 33080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 3309fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 33100b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 3311fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3312fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 3313fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 33140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 3315fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 33160b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 3317fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 33180b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 3319fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3320fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 3321fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 33220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 3323fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 3324bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 3325aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 3326aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 3327aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 3328fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 3329bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 3330aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 3331aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 3332aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 3333fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 333473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 333573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 333673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 3337f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 3338f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 3339f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 3340f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 3341f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 3342f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 3343f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 3344f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 3345f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 334673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 3347fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3348fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 334973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 335073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 3351fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3353fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 3354162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 3355ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 3356a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 3357ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 3358fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 3359fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 33600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 33611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3362d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 33631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3364d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 3365e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 336678d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 336778d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky if (!VD->hasGlobalStorage()) 336878d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky S.Diag(Attr.getLoc(), 336978d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky diag::warn_attribute_requires_functions_or_static_globals) 337078d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky << Attr.getName(); 337178d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky } else if (!isFunctionOrMethod(D)) { 337278d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky S.Diag(Attr.getLoc(), 337378d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky diag::warn_attribute_requires_functions_or_static_globals) 337478d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky << Attr.getName(); 3375d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 3376d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 3377bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3378768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 3379d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 3380d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 33811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 33825bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 33831731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 33845bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 33851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3386bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 338787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 33885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3389883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 33905bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 33915bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 3392bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3393768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 33945bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 33955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 33961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 33971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 33987255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 33991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 34007255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 34011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 34027255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 340387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 34047255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3405883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 34067255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 34077255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 34087255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 3409768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 3410f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 34117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 34127255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 34130557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hinesstatic void handleKernelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 34140557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines if (S.LangOpts.Renderscript) { 34150557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines D->addAttr(::new (S.Context) KernelAttr(Attr.getRange(), S.Context)); 34160557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines } else { 34170557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "kernel"; 34180557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines } 34190557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines} 34200557d08ce20c3568b1d8bda298fa47b5488f0d26Stephen Hines 34211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3422ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3423ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 3424831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 3425ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3426ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3427ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3428ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 3430ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3431883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 3432ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3433ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3434ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3435768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 3436ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3437ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 3438ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3439ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3440ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 34411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3442ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3443ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 3444ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 3445ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3446ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3447ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3448ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 344987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 3450ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3451883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 3452ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3453ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3454ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3455768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 3456ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3457ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 3458ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3459ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3460ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 34611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3462ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3463ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 34641731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3465ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3466ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 346787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 3468ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3469883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 3470ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3471ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3472ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 347387c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 34742c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 3475723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 34762c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 34772c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 34782c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 34792c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 34802c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 34812c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 34822c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 34832c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 34842c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 34852c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 34862c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 34872c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 3488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 3489ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3490ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 3491ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3492ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3493ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 34941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3495ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3496ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 34971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3498ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 34991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3500ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 350187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 3502ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3503883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 3504ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3505ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3506ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3507768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 3508ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3509ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 3510ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3511ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3512ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 35131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3514ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3515ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 35161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3517ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 35181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3519ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 352087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 3521ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3522883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 3523ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3524ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3525ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3526768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 3527ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3528ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 3529ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3530ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3531ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 35321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 353326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 35341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 353526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 3536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 353787c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 3538c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 353926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3540883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 354126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 354226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 3543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 35440130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 3545cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 3546c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 3547c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 3548bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3549768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 355026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 355126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 35521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 355387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3554711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 355587c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 3556e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 3557711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 355887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 3559711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3560e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 356187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 356287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 356387c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3564711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3565711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3566711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 356787c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 35688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_FastCall: 3569768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 3570e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 35718e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_StdCall: 3572768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 3573e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 35748e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ThisCall: 3575768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 357604633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 35778e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CDecl: 3578768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 3579e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 35808e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pascal: 3581768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 358252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 35838e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pcs: { 3584414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 35859071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer switch (CC) { 35869071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer case CC_AAPCS: 3587414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 35889071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer break; 35899071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer case CC_AAPCS_VFP: 3590414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 35919071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer break; 35929071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer default: 35939071defafbcfb5d21bb6d49bb9c0f0366db39e08Benjamin Kramer llvm_unreachable("unexpected calling convention in pcs attribute"); 3594414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3595414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 3596768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 3597414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3598e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 3599e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 3600e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 3601e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 3602e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 360456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 3605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 3606f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 3607f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 3608711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 3609711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 3610711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3611711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3612fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0; 3613fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) { 3614fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << ReqArgs; 3615711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 3616711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3617ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 361855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3619414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 3620414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 3621711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 36228e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CDecl: CC = CC_C; break; 36238e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_FastCall: CC = CC_X86FastCall; break; 36248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_StdCall: CC = CC_X86StdCall; break; 36258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ThisCall: CC = CC_X86ThisCall; break; 36268e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pascal: CC = CC_X86Pascal; break; 36278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pcs: { 3628414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 3629414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 36305cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3631414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3632414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 3633414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 3634414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 3635414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3636414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 36375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3638414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 3639414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 3640414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3641414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 3642414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 3643414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3644414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3645fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer 3646fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer attr.setInvalid(); 3647fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer Diag(attr.getLoc(), diag::err_invalid_pcs); 3648fac8e43390fad67a5d02c9876e860496fee01868Benjamin Kramer return true; 3649414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 36507530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("unexpected attribute kind"); 3651711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3652711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3653711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3654711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3655711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 36561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 365787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3658711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3659711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 366087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3661711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3662711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 366387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 366487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 366587c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3666ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3667ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 366855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3669768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3670711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3671711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3672711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3673711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 367487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 367587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3676711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3677711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 367887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 367987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 368087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3681711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3682711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3683711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 368487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 368555d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3686ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3687711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 368887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 368955d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 369087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3691711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 369255d3aaf9a537888734762170823daf750ea9036dEli Friedman } 369355d3aaf9a537888734762170823daf750ea9036dEli Friedman 3694bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 369587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 369655d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 369787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3698711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 369955d3aaf9a537888734762170823daf750ea9036dEli Friedman } 370055d3aaf9a537888734762170823daf750ea9036dEli Friedman 3701711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3702bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 370387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3704bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 370587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3706711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 370755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 370855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3709711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3710ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3711ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 37121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 37137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 37147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 37157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3716bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3717bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 37187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 37197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 372187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 37227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3723883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 37247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 37257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 37277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 37287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 37297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 37307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 37317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 37327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 37337b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 37347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 37357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 37377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 37387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 37397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 37407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 37417b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 37427b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 37437b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 37447b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 37457b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 37467b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37477b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37487b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 3749768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 37507b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 37517b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 37527b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 37537b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 37547b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 37557b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 37567b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 37570d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, 37580d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const AttributeList &Attr) { 37590d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko StringRef AttrName = Attr.getName()->getName(); 37600d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!Attr.getParameterName()) { 37610d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier) 37620d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << Attr.getName() << /* arg num = */ 1; 37630d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 37640d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 37650d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37660d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (Attr.getNumArgs() != 2) { 37670d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 37680d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << /* required args = */ 3; 37690d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 37700d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 37710d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37720d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko IdentifierInfo *ArgumentKind = Attr.getParameterName(); 37730d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37740d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 37750d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 37760d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << Attr.getName() << ExpectedFunctionOrMethod; 37770d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 37780d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 37790d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37800d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko uint64_t ArgumentIdx; 37810d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 37820d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getLoc(), 2, 37830d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getArg(0), ArgumentIdx)) 37840d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 37850d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37860d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko uint64_t TypeTagIdx; 37870d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName, 37880d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getLoc(), 3, 37890d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getArg(1), TypeTagIdx)) 37900d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 37910d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 37920d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko bool IsPointer = (AttrName == "pointer_with_type_tag"); 37930d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (IsPointer) { 37940d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko // Ensure that buffer has a pointer type. 37950d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx); 37960d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!BufferTy->isPointerType()) { 37970d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only) 37980d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << AttrName; 37990d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 38000d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 38010d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 38020d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(), 38030d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Context, 38040d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko ArgumentKind, 38050d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko ArgumentIdx, 38060d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko TypeTagIdx, 38070d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko IsPointer)); 38080d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko} 38090d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 38100d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenkostatic void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, 38110d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko const AttributeList &Attr) { 38120d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko IdentifierInfo *PointerKind = Attr.getParameterName(); 38130d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko if (!PointerKind) { 38140d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier) 38150d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko << "type_tag_for_datatype" << 1; 38160d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko return; 38170d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko } 38180d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 38190d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL); 38200d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 38210d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko D->addAttr(::new (S.Context) TypeTagForDatatypeAttr( 38220d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getRange(), 38230d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko S.Context, 38240d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko PointerKind, 38250d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko MatchingCType, 38260d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getLayoutCompatible(), 38270d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko Attr.getMustBeNull())); 38280d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko} 38290d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 38300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3831b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3832b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3833b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3834c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 383508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao return type->isDependentType() || 383608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao type->isObjCObjectPointerType() || 38376c73a2975ba9112787380abd878876336957b3f6Douglas Gregor S.Context.isObjCNSObjectType(type); 3838c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3839c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 384008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao return type->isDependentType() || 384108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao type->isPointerType() || 38426c73a2975ba9112787380abd878876336957b3f6Douglas Gregor isValidSubjectOfNSAttribute(S, type); 3843c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3844c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 38451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 384687c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3847c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 384887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3849768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedParameter; 3850c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3851c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3852c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3853c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 38548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt if (Attr.getKind() == AttributeList::AT_NSConsumed) { 3855c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3856c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3857c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3858c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3859c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3860c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3861c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3862c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 386387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3864768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << cf; 3865c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3866c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3867c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3868c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 3869768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3870c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 3871768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3872c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3873c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 38741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 38751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 387687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 387787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3878768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedMethod; 3879c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3880c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3881c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3882768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3883c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3884c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 38851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 38861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3887b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3888c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3889bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 389087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3891c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 38924e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 38938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt (Attr.getKind() == AttributeList::AT_NSReturnsRetained)) 3894f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 3895a23bd4cec36d7f29065418f84ef48395fcbe6254Fariborz Jahanian else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3896a23bd4cec36d7f29065418f84ef48395fcbe6254Fariborz Jahanian returnType = PD->getType(); 389787c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3898c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 38995dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 390087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3901768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() 3902883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3903b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3904b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3906c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3907c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 390887c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 39097530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("invalid ownership attribute"); 39108e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsAutoreleased: 39118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsRetained: 39128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsNotRetained: 3913c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3914c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3915c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3916c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 39178e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsRetained: 39188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsNotRetained: 3919c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3920c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3921c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3922c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3923c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3924c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 392587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3926768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 39285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3929bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 393087c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3931b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3932b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ownership attribute"); 39338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsAutoreleased: 3934768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3935c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3936c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 39378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsNotRetained: 3938768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3939f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 394031c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 39418e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsNotRetained: 3942768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3943f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 394431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 39458e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsRetained: 3946768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3947f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3948b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 39498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsRetained: 3950768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3951f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3952b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3953b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3954b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3955b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3956dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3957dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3958dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3959dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3960dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3961dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 396294d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian if (!method) { 39630e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3964f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 3965dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3966dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3967dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3968dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3969dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 397008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 3971f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian if (!resultType->isReferenceType() && 3972f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3973dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3974dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3975dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3976dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3977dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3978dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3979dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3980dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3981dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3983dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3984dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3985841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanianstatic void handleObjCRequiresSuperAttr(Sema &S, Decl *D, 3986841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian const AttributeList &attr) { 3987841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian SourceLocation loc = attr.getLoc(); 3988841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3989841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian 3990841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian if (!method) { 3991841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3992841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 3993841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian return; 3994841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian } 3995841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian DeclContext *DC = method->getDeclContext(); 3996841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) { 3997841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 3998841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian << attr.getName() << 0; 3999841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian S.Diag(PDecl->getLocation(), diag::note_protocol_decl); 4000841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian return; 4001841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian } 4002841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian if (method->getMethodFamily() == OMF_dealloc) { 4003841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol) 4004841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian << attr.getName() << 1; 4005841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian return; 4006841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian } 4007841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian 4008841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian method->addAttr( 4009841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian ::new (S.Context) ObjCRequiresSuperAttr(attr.getRange(), S.Context)); 4010841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian} 4011841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian 40128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer. 40138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 40148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!isa<FunctionDecl>(D)) { 40158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4016f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << A.getRange() << A.getName() << ExpectedFunction; 40178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 40188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 40198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 40208e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer); 40218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 40228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Check whether there's a conflicting attribute already present. 40238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Attr *Existing; 40248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 40258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFUnknownTransferAttr>(); 40268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 40278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFAuditedTransferAttr>(); 40288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 40298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (Existing) { 40308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 40318dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getName() 40328dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 40338dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << Existing->getRange(); 40348dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 40358dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 40368dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 40378dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // All clear; add the attribute. 40388dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 40398dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 40408dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 40418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 40428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 40438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 40448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 40458dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 40468dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 4047fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 4048fe98da0fa352462c02db037360788748f95466f7John McCall const AttributeList &Attr) { 4049fe98da0fa352462c02db037360788748f95466f7John McCall RecordDecl *RD = dyn_cast<RecordDecl>(D); 4050fe98da0fa352462c02db037360788748f95466f7John McCall if (!RD || RD->isUnion()) { 4051fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4052f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedStruct; 4053fe98da0fa352462c02db037360788748f95466f7John McCall } 4054fe98da0fa352462c02db037360788748f95466f7John McCall 4055fe98da0fa352462c02db037360788748f95466f7John McCall IdentifierInfo *ParmName = Attr.getParameterName(); 4056fe98da0fa352462c02db037360788748f95466f7John McCall 4057fe98da0fa352462c02db037360788748f95466f7John McCall // In Objective-C, verify that the type names an Objective-C type. 4058fe98da0fa352462c02db037360788748f95466f7John McCall // We don't want to check this outside of ObjC because people sometimes 4059fe98da0fa352462c02db037360788748f95466f7John McCall // do crazy C declarations of Objective-C types. 40604e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (ParmName && S.getLangOpts().ObjC1) { 4061fe98da0fa352462c02db037360788748f95466f7John McCall // Check for an existing type with this name. 4062fe98da0fa352462c02db037360788748f95466f7John McCall LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 4063fe98da0fa352462c02db037360788748f95466f7John McCall Sema::LookupOrdinaryName); 4064fe98da0fa352462c02db037360788748f95466f7John McCall if (S.LookupName(R, Sc)) { 4065fe98da0fa352462c02db037360788748f95466f7John McCall NamedDecl *Target = R.getFoundDecl(); 4066fe98da0fa352462c02db037360788748f95466f7John McCall if (Target && !isa<ObjCInterfaceDecl>(Target)) { 4067fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 4068fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(Target->getLocStart(), diag::note_declared_at); 4069fe98da0fa352462c02db037360788748f95466f7John McCall } 4070fe98da0fa352462c02db037360788748f95466f7John McCall } 4071fe98da0fa352462c02db037360788748f95466f7John McCall } 4072fe98da0fa352462c02db037360788748f95466f7John McCall 4073fe98da0fa352462c02db037360788748f95466f7John McCall D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 4074fe98da0fa352462c02db037360788748f95466f7John McCall ParmName)); 4075fe98da0fa352462c02db037360788748f95466f7John McCall} 4076fe98da0fa352462c02db037360788748f95466f7John McCall 40771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 40781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 407987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 4080f85e193739c953358c865005855253af4f68a497John McCall 408187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4082f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 4083f85e193739c953358c865005855253af4f68a497John McCall} 4084f85e193739c953358c865005855253af4f68a497John McCall 40851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 40861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 408787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 408887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 4089f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 4090f85e193739c953358c865005855253af4f68a497John McCall return; 4091f85e193739c953358c865005855253af4f68a497John McCall } 4092f85e193739c953358c865005855253af4f68a497John McCall 409387c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 4094f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 4095f85e193739c953358c865005855253af4f68a497John McCall 4096f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 4097f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 409887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 4099f85e193739c953358c865005855253af4f68a497John McCall << type; 4100f85e193739c953358c865005855253af4f68a497John McCall return; 4101f85e193739c953358c865005855253af4f68a497John McCall } 4102f85e193739c953358c865005855253af4f68a497John McCall 4103f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 4104f85e193739c953358c865005855253af4f68a497John McCall 4105f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 4106f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 4107f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 4108f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 4109f85e193739c953358c865005855253af4f68a497John McCall 4110f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 4111f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 4112f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 4113f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 4114f85e193739c953358c865005855253af4f68a497John McCall break; 4115f85e193739c953358c865005855253af4f68a497John McCall 4116f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 4117f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 4118f85e193739c953358c865005855253af4f68a497John McCall break; 4119f85e193739c953358c865005855253af4f68a497John McCall 4120f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 4121f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 412287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 4123f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 4124f85e193739c953358c865005855253af4f68a497John McCall break; 4125f85e193739c953358c865005855253af4f68a497John McCall } 4126f85e193739c953358c865005855253af4f68a497John McCall 412787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 4128768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 4129f85e193739c953358c865005855253af4f68a497John McCall} 4130f85e193739c953358c865005855253af4f68a497John McCall 413111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 413211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 413311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 413411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 41351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 413662ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 413711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 41381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 413911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 41401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 414111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 414211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 41435cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 4144d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 4145d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 4146d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 4147d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 4148d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 41495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 4150d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 4151d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 4152d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 4153f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 4154d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 4155d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 4156d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 4157d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 4158d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 4159d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 4160d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 4161d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 4162d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 4163d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 4164f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 4165d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 41665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 4167f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 4168f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 4169f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 4170f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 4171d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 4172d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 4173d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 4174d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 4175d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 4176d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 4177d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 4178d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 4179d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 4180d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 4181d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 418211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 4183768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 418411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 4185d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 418611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 4187f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 4188f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 4189c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4190c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (S.LangOpts.MicrosoftExt) { 4191c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall AttributeList::Kind Kind = Attr.getKind(); 41928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt if (Kind == AttributeList::AT_SingleInheritance) 4193c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4194c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context)); 41958e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt else if (Kind == AttributeList::AT_MultipleInheritance) 4196c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4197c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context)); 41988e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt else if (Kind == AttributeList::AT_VirtualInheritance) 4199c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4200c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context)); 4201c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } else 4202c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 4203c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 4204c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 4205c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4206c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (S.LangOpts.MicrosoftExt) { 4207c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall AttributeList::Kind Kind = Attr.getKind(); 42088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt if (Kind == AttributeList::AT_Ptr32) 4209c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4210c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context)); 42118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt else if (Kind == AttributeList::AT_Ptr64) 4212c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4213c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context)); 42148e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt else if (Kind == AttributeList::AT_Win64) 4215c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 4216c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Win64Attr(Attr.getRange(), S.Context)); 4217c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } else 4218c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 4219c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 4220c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 4221adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencerstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 4222adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer if (S.LangOpts.MicrosoftExt) 4223adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context)); 4224adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer else 4225adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 4226adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer} 4227adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer 4228b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 42290744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 42300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 42310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 42321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 42331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 423460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 42358e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDADevice: handleDeviceAttr (S, D, Attr); break; 42368e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDAHost: handleHostAttr (S, D, Attr); break; 42378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break; 4238e559b0dc6de871f73eb4db6378c65552e95e83e7Shih-wei Liao case AttributeList::AT_Kernel: handleKernelAttr (S, D, Attr); break; 423960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 424060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 424160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 424260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 4243e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 42441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 42451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 4246803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 42478e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 42488e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 42498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_IBOutletCollection: 42501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 42518e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AddressSpace: 42528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_OpenCLImageAccess: 42538e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCGC: 42548e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_VectorSize: 42558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NeonVectorType: 42568e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NeonPolyVectorType: 4257bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 4258bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 4259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 42608e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDADevice: 42618e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDAHost: 42628e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Overloadable: 426308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao case AttributeList::AT_Kernel: 426460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 426560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 426660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 42678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break; 42688e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break; 42698e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AllocSize: handleAllocSizeAttr (S, D, Attr); break; 42708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AlwaysInline: 42711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 42728e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AnalyzerNoReturn: 42731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 42745e2d5dec7736f6f9292d4212dec67295909f1328Hans Wennborg case AttributeList::AT_TLSModel: handleTLSModelAttr (S, D, Attr); break; 42758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Annotate: handleAnnotateAttr (S, D, Attr); break; 42768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break; 42778e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CarriesDependency: 42781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 42798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Common: handleCommonAttr (S, D, Attr); break; 42808e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDAConstant:handleConstantAttr (S, D, Attr); break; 42818e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break; 42828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Deprecated: 4283bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated"); 4284bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer break; 42858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Destructor: handleDestructorAttr (S, D, Attr); break; 42868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ExtVectorType: 42871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 42883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 42898e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break; 42908e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break; 42918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break; 42928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_GNUInline: handleGNUInlineAttr (S, D, Attr); break; 42938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDALaunchBounds: 42941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 42957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 42968e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Mode: handleModeAttr (S, D, Attr); break; 42978e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Malloc: handleMallocAttr (S, D, Attr); break; 42988e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_MayAlias: handleMayAliasAttr (S, D, Attr); break; 42998e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoCommon: handleNoCommonAttr (S, D, Attr); break; 43008e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NonNull: handleNonNullAttr (S, D, Attr); break; 4301dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 4302dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 4303dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 43041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 43058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Cold: handleColdAttr (S, D, Attr); break; 43068e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Hot: handleHotAttr (S, D, Attr); break; 43078e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Naked: handleNakedAttr (S, D, Attr); break; 43088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoReturn: handleNoReturnAttr (S, D, Attr); break; 43098e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoThrow: handleNothrowAttr (S, D, Attr); break; 43108e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CUDAShared: handleSharedAttr (S, D, Attr); break; 43118e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_VecReturn: handleVecReturnAttr (S, D, Attr); break; 43128e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt 43138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCOwnership: 43141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 43158e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCPreciseLifetime: 43161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 4317f85e193739c953358c865005855253af4f68a497John McCall 43188e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCReturnsInnerPointer: 4319dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 4320dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 4321841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian case AttributeList::AT_ObjCRequiresSuper: 4322841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian handleObjCRequiresSuperAttr(S, D, Attr); break; 4323841011373b345cf79d0da4b7242dcf2869a43502Fariborz Jahanian 43248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSBridged: 4325fe98da0fa352462c02db037360788748f95466f7John McCall handleNSBridgedAttr(S, scope, D, Attr); break; 4326fe98da0fa352462c02db037360788748f95466f7John McCall 43278e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFAuditedTransfer: 43288e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFUnknownTransfer: 43298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall handleCFTransferAttr(S, D, Attr); break; 43308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 4331b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 43328e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFConsumed: 43338e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSConsumed: handleNSConsumedAttr (S, D, Attr); break; 43348e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSConsumesSelf: 43351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 4336c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 43378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsAutoreleased: 43388e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsNotRetained: 43398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsNotRetained: 43408e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NSReturnsRetained: 43418e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CFReturnsRetained: 43421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 4343b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 43440df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner case AttributeList::AT_WorkGroupSizeHint: 43458e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ReqdWorkGroupSize: 43460df579ec000ffe52e0cddf1e7ee5e50a55256835Tanya Lattner handleWorkGroupSize(S, D, Attr); break; 43476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 434808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao case AttributeList::AT_InitPriority: 43491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 435008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao 43518e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Packed: handlePackedAttr (S, D, Attr); break; 43528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Section: handleSectionAttr (S, D, Attr); break; 43538e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Unavailable: 4354bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable"); 4355bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer break; 435608fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao case AttributeList::AT_ArcWeakrefUnavailable: 435708fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao handleArcWeakrefUnavailableAttr (S, D, Attr); 4358742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 43598e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCRootClass: 4360b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard handleObjCRootClassAttr(S, D, Attr); 4361b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard break; 436208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao case AttributeList::AT_ObjCRequiresPropertyDefs: 436308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao handleObjCRequiresPropertyDefsAttr (S, D, Attr); 4364e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian break; 43658e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Unused: handleUnusedAttr (S, D, Attr); break; 43668e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ReturnsTwice: 4367f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola handleReturnsTwiceAttr(S, D, Attr); 4368f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola break; 43698e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Used: handleUsedAttr (S, D, Attr); break; 43708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Visibility: handleVisibilityAttr (S, D, Attr); break; 43718e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr); 4372026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 43738e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Weak: handleWeakAttr (S, D, Attr); break; 43748e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_WeakRef: handleWeakRefAttr (S, D, Attr); break; 43758e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_WeakImport: handleWeakImportAttr (S, D, Attr); break; 43768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_TransparentUnion: 43771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 4378803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 43798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCException: 43801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 43810db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 43828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCMethodFamily: 43831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 4384d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 43858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ObjCNSObject:handleObjCNSObject (S, D, Attr); break; 43868e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Blocks: handleBlocksAttr (S, D, Attr); break; 43878e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Sentinel: handleSentinelAttr (S, D, Attr); break; 43888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Const: handleConstAttr (S, D, Attr); break; 43898e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pure: handlePureAttr (S, D, Attr); break; 43908e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Cleanup: handleCleanupAttr (S, D, Attr); break; 43918e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoDebug: handleNoDebugAttr (S, D, Attr); break; 43928e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoInline: handleNoInlineAttr (S, D, Attr); break; 43938e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Regparm: handleRegparmAttr (S, D, Attr); break; 4394bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 439505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 439605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 43978e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. 43981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 43997255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 44008e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_StdCall: 44018e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CDecl: 44028e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_FastCall: 44038e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ThisCall: 44048e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pascal: 44058e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Pcs: 44061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 440704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 44088e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_OpenCLKernel: 44091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 4410f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 4411c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 4412c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall // Microsoft attributes: 44138e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_MsStruct: 4414c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handleMsStructAttr(S, D, Attr); 4415c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 44168e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Uuid: 44171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 441811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 44198e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_SingleInheritance: 44208e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_MultipleInheritance: 44218e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_VirtualInheritance: 4422c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handleInheritanceAttr(S, D, Attr); 4423c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 44248e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Win64: 44258e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Ptr32: 44268e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Ptr64: 4427c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handlePortabilityAttr(S, D, Attr); 4428c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 44298e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ForceInline: 4430adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer handleForceInlineAttr(S, D, Attr); 4431adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer break; 4432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 44348e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_GuardedVar: 4435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 4436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 44378e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_PtGuardedVar: 4438dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handlePtGuardedVarAttr(S, D, Attr); 4439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 44408e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ScopedLockable: 4441dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleScopedLockableAttr(S, D, Attr); 4442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 44438e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoAddressSafetyAnalysis: 444471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany handleNoAddressSafetyAttr(S, D, Attr); 444571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany break; 44468e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoThreadSafetyAnalysis: 4447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 4448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 44498e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_Lockable: 4450fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 4451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 44528e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_GuardedBy: 4453db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 4454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44558e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_PtGuardedBy: 4456dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handlePtGuardedByAttr(S, D, Attr); 4457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44588e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ExclusiveLockFunction: 4459dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleExclusiveLockFunctionAttr(S, D, Attr); 4460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44618e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ExclusiveLocksRequired: 4462dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleExclusiveLocksRequiredAttr(S, D, Attr); 4463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44648e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_ExclusiveTrylockFunction: 4465dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleExclusiveTrylockFunctionAttr(S, D, Attr); 4466db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44678e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_LockReturned: 4468db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 4469db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44708e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_LocksExcluded: 4471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 4472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44738e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_SharedLockFunction: 4474dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleSharedLockFunctionAttr(S, D, Attr); 4475db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44768e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_SharedLocksRequired: 4477dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleSharedLocksRequiredAttr(S, D, Attr); 4478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44798e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_SharedTrylockFunction: 4480dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleSharedTrylockFunctionAttr(S, D, Attr); 4481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44828e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_UnlockFunction: 4483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 4484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44858e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AcquiredBefore: 4486dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleAcquiredBeforeAttr(S, D, Attr); 4487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 44888e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_AcquiredAfter: 4489dc69157f9bfa538e2bf62a01fa46df22ce45ce3cMichael Han handleAcquiredAfterAttr(S, D, Attr); 4490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 44920d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko // Type safety attributes. 44930d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko case AttributeList::AT_ArgumentWithTypeTag: 44940d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko handleArgumentWithTypeTagAttr(S, D, Attr); 44950d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko break; 44960d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko case AttributeList::AT_TypeTagForDatatype: 44970d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko handleTypeTagForDatatypeAttr(S, D, Attr); 44980d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko break; 44990d5a069f66df09b3308ccfdce84a88170034c657Dmitri Gribenko 4500803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 450182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 450282d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 450382d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 450408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ? 450508fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao diag::warn_unhandled_ms_attribute_ignored : 4506fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman diag::warn_unknown_attribute_ignored) << Attr.getName(); 4507803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 4508803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 4509803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 4510803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 451160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 451260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 451360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 451460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 45151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 45161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 451760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 451860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 451960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 452060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 452108fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // Type attributes are still treated as declaration attributes by 452208fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes. We don't 452308fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // want to process them, however, because we will simply warn about ignoring 4524fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman // them. So instead, we will bail out early. 4525fc685ace387734599c475426b1a8efdb491054b8Aaron Ballman if (Attr.isMSTypespecAttribute()) 452660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 452760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 452860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 45291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 453060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 453160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 45321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 453360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 453460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 4535803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 4536803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 4537f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 453860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 453960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 454011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 45411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 454211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 454311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 454411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 454511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 454611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 454760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 454811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 4549dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 455011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 4551803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 4552803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 4553803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 45545f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access 45555f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier. 45565f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 45575f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen const AttributeList *AttrList) { 45585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen for (const AttributeList* l = AttrList; l; l = l->getNext()) { 45598e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt if (l->getKind() == AttributeList::AT_Annotate) { 45605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen handleAnnotateAttr(*this, ASDecl, *l); 45615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } else { 45625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 45635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return true; 45645f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 45655f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 45665f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 45675f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return false; 45685f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen} 45695f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 4570e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it 4571e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about. 4572e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 4573e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for ( ; A; A = A->getNext()) { 4574e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall // Only warn if the attribute is an unignored, non-type attribute. 4575e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->isUsedAsTypeAttr()) continue; 4576e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::IgnoredAttribute) continue; 4577e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4578e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::UnknownAttribute) { 4579e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 4580e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 4581e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } else { 4582e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 4583e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 4584e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 4585e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 4586e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 4587e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4588e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being 4589e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes 4590e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it. 4591e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 4592e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 4593e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getAttributes()); 4594e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 4595e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 4596e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 4597e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4598e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 45991dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \#pragma weak needs a non-definition decl and source may not have one. 4600900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 4601900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 46027b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 4603e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 4604e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4605900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 4606900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 4607900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 4608900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 4609900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 4610900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 4611900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 4612900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 4613900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 4614900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 4615900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 4616900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 4617900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 4618900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 4619900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 4620c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 4621900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 4622900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 4623900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 4624900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 4625900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 4626900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 4627900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 4628900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 4629900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 4630900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 4631900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 4632900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 46334278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie NewFD->setParams(Params); 4634b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 4635e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 4636e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 4637ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 4638a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 463916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 464016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 4641b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 4642b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 4643c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 4644b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 4645e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4646e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 4647e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 4648e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 46491dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak 4650e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 46517b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 4652c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 4653c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 4654c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 4655c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 4656900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 4657cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 4658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 4659cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 4660c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 4661c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 4662c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 4663c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 4664c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 4665c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 4666c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 4667c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 4668cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 4669e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4670e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 4671e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 46720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 46730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 46740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 467560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 467660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 4677d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 4678d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 467931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 468031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 468131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 468231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 468331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 468431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 468531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 468631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 468731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 468831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 468931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 469031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 4691d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 4692e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4693e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4694e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4695e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 46960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 46977f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 469860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 4699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 47000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 47010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 47020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 47030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 47040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 47050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 470660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 4707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 47080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 47090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 471060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 47110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 471254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4713f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 4714f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 4715f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 4716f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 4717f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 4718a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian // Function declarations in sys headers will be marked unavailable. 4719a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 4720a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian !isa<FunctionDecl>(decl)) 4721f85e193739c953358c865005855253af4f68a497John McCall return false; 4722f85e193739c953358c865005855253af4f68a497John McCall 4723f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 4724f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 4725f85e193739c953358c865005855253af4f68a497John McCall} 4726f85e193739c953358c865005855253af4f68a497John McCall 4727f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 4728f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 4729f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 4730f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 4731f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 4732f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 4733f85e193739c953358c865005855253af4f68a497John McCall return; 4734f85e193739c953358c865005855253af4f68a497John McCall } 47354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount) 4736175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 473748d798ce32447607144db70a484cdb99c1180663Benjamin Kramer // FIXME: we may want to suppress diagnostics for all 473808fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao // kind of forbidden type messages on unavailable functions. 4739175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (FD->hasAttr<UnavailableAttr>() && 474008fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao diag.getForbiddenTypeDiagnostic() == 4741175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag::err_arc_array_param_no_ownership) { 4742175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.Triggered = true; 4743175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian return; 4744175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4745175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4746f85e193739c953358c865005855253af4f68a497John McCall 4747f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 4748f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 4749f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 4750f85e193739c953358c865005855253af4f68a497John McCall} 4751f85e193739c953358c865005855253af4f68a497John McCall 47529257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 47539257664568bf375b7790131a84d9a4fa30a5b7e3John McCall assert(DelayedDiagnostics.getCurrentPool()); 475413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 47559257664568bf375b7790131a84d9a4fa30a5b7e3John McCall DelayedDiagnostics.popWithoutEmitting(state); 47569257664568bf375b7790131a84d9a4fa30a5b7e3John McCall 47579257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // When delaying diagnostics to run in the context of a parsed 47589257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // declaration, we only want to actually emit anything if parsing 47599257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // succeeds. 47609257664568bf375b7790131a84d9a4fa30a5b7e3John McCall if (!decl) return; 47619257664568bf375b7790131a84d9a4fa30a5b7e3John McCall 47629257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // We emit all the active diagnostics in this pool or any of its 47639257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // parents. In general, we'll get one pool for the decl spec 47649257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // and a child pool for each declarator; in a decl group like: 47659257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // deprecated_typedef foo, *bar, baz(); 47669257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // only the declarator pops will be passed decls. This is correct; 47679257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // we really do need to consider delayed diagnostics from the decl spec 47689257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // for each of the different declarations. 476913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall const DelayedDiagnosticPool *pool = &poppedPool; 47709257664568bf375b7790131a84d9a4fa30a5b7e3John McCall do { 477113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall for (DelayedDiagnosticPool::pool_iterator 47729257664568bf375b7790131a84d9a4fa30a5b7e3John McCall i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 47739257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // This const_cast is a bit lame. Really, Triggered should be mutable. 47749257664568bf375b7790131a84d9a4fa30a5b7e3John McCall DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 4775eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 47762f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 47772f514480c448708ec382a684cf5e035d3a827ec8John McCall 4778eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 47792f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 4780e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall // Don't bother giving deprecation diagnostics if the decl is invalid. 4781e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (!decl->isInvalidDecl()) 47829257664568bf375b7790131a84d9a4fa30a5b7e3John McCall HandleDelayedDeprecationCheck(diag, decl); 47832f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 47842f514480c448708ec382a684cf5e035d3a827ec8John McCall 47852f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 47869257664568bf375b7790131a84d9a4fa30a5b7e3John McCall HandleDelayedAccessCheck(diag, decl); 47872f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 4788f85e193739c953358c865005855253af4f68a497John McCall 4789f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 47909257664568bf375b7790131a84d9a4fa30a5b7e3John McCall handleDelayedForbiddenType(*this, diag, decl); 4791f85e193739c953358c865005855253af4f68a497John McCall break; 479254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 479354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 47949257664568bf375b7790131a84d9a4fa30a5b7e3John McCall } while ((pool = pool->getParent())); 47952f514480c448708ec382a684cf5e035d3a827ec8John McCall} 479658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 479713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Given a set of delayed diagnostics, re-emit them as if they had 479813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// been delayed in the current context instead of in the given pool. 479913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Essentially, this just moves them to the current pool. 480013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCallvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 480113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 480213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall assert(curPool && "re-emitting in undelayed context not supported"); 480313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall curPool->steal(pool); 48042f514480c448708ec382a684cf5e035d3a827ec8John McCall} 48052f514480c448708ec382a684cf5e035d3a827ec8John McCall 48062f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 48072f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 48080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 48092f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 4810c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // A category implicitly has the availability of the interface. 4811c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 4812c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis return CatD->getClassInterface()->isDeprecated(); 48132f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 48142f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 48152f514480c448708ec382a684cf5e035d3a827ec8John McCall} 48162f514480c448708ec382a684cf5e035d3a827ec8John McCall 4817c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedmanstatic void 4818c3b2308f66fe8abd2c1a911b500c0b989c295819Eli FriedmanDoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message, 4819c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman SourceLocation Loc, 4820c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman const ObjCInterfaceDecl *UnknownObjCClass) { 4821c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman DeclarationName Name = D->getDeclName(); 4822c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman if (!Message.empty()) { 4823c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(Loc, diag::warn_deprecated_message) << Name << Message; 4824c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(D->getLocation(), 4825c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 4826c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman : diag::note_previous_decl) << Name; 4827c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman } else if (!UnknownObjCClass) { 4828c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 4829c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(D->getLocation(), 4830c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 4831c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman : diag::note_previous_decl) << Name; 4832c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman } else { 4833c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name; 4834c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 4835c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman } 4836c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman} 4837c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman 48389c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 48392f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 48402f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 48412f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 48422f514480c448708ec382a684cf5e035d3a827ec8John McCall 48432f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 4844c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(), 4845c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman DD.getDeprecationMessage(), DD.Loc, 4846c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman DD.getUnknownObjCClass()); 484754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 484854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 48495f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 48508e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 485189ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 485254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 4853eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 485408fc8eb5a1cc9c01af67e016ab21c9b905711eb1Shih-wei Liao DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 4855b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian UnknownObjCClass, 4856b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Message)); 485754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 485854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 485954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 486054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 48613a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 486254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 4863c3b2308f66fe8abd2c1a911b500c0b989c295819Eli Friedman DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass); 486454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 4865