SemaDeclAttr.cpp revision 0e78afbb15c6f51932e562e620f714c37cf914e6
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h" 19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 25fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h" 26797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 32b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind { 33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 43db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedVariableFunctionOrLabel, 44f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor ExpectedFieldOrGlobalVar, 45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor ExpectedStruct 46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall}; 47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall 48e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 5287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D, 53a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 5587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 5787c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 5987c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 63bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 656217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 66755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 69183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 75d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 76a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 7787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) { 7887c44604325578b8de07d768391c1c9432404f5aChandler Carruth return getFunctionType(D, false) != NULL; 79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 8487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) { 8587c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isFunction(D)|| isa<ObjCMethodDecl>(D); 86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 9187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) { 9287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethod(D)) 93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 9987c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<BlockDecl>(D); 100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 10487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) { 105f85e193739c953358c865005855253af4f68a497John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 10687c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth isa<ObjCPropertyDecl>(D); 108711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 110d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 112620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 11387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) { 11487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 11572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 116620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 118d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 1203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 12587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) { 12687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 12772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 12887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 129d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 13087c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_size(); 1313568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 13387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 13487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 13572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 13687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 137d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 1403568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 14287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) { 14387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 1445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 14587c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->getResultType(); 1465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 14887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) { 14987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) { 15072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 153db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 154d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->isVariadic(); 1563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 15987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) { 16087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 16107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 166183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 167b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 169bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 170506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 175bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 181085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1826217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 183085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1866217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 189bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 191465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 192085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 197b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May 198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 1991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth unsigned int Num) { 2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (Attr.getNumArgs() != Num) { 2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return false; 2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth } 2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return true; 2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth} 2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 209db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 210b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May 211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int Num) { 214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (Attr.getNumArgs() < Num) { 215db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return false; 217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return true; 220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// 223fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var 224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable 225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 22639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) { 227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (isa<FieldDecl>(D)) 228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 22939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 235b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool. 236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) { 237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = Exp->getType(); 238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return QT->isBooleanType() || QT->isIntegerType(); 239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 241fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 242fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type. 243fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message. 244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise 245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 246ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 247ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 24839997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 249fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski QualType QT = vd->getType(); 25039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (QT->isAnyPointerType()) 251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 252ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName()->getName() << QT; 254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } else { 255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName(); 257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 261b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points 262b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit. 2637d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) { 2647d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const RecordType *RT = QT->getAs<RecordType>()) 265b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return RT; 2667d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2677d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer // Now check if we point to record type. 2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const PointerType *PT = QT->getAs<PointerType>()) 2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return PT->getPointeeType()->getAs<RecordType>(); 2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return 0; 272b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 273b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 2743ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType 275ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object. 27683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 27783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins QualType Ty) { 27883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins const RecordType *RT = getRecordType(Ty); 27983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins 28083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins // Warn if could not get record type for this argument. 281d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT) { 282ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class) 28383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 28483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 286634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins // Don't check for lockable if the class hasn't been defined yet. 287634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins if (RT->isIncompleteType()) 28883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 28983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins // Warn if the type is not lockable. 290d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT->getDecl()->getAttr<LockableAttr>()) { 291ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 29283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 29383cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 2953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski} 2963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 297b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 298ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object. 2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with. 3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function 3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list. 302ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 3033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const AttributeList &Attr, 3043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVectorImpl<Expr*> &Args, 305b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski int Sidx = 0, 306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool ParamIdxOk = false) { 3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 308b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski Expr *ArgExp = Attr.getArg(Idx); 3093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski if (ArgExp->isTypeDependent()) { 311ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // FIXME -- need to check this again on template instantiation 312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski Args.push_back(ArgExp); 313ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski continue; 314ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski } 315b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 316ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (isa<StringLiteral>(ArgExp)) { 317ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // We allow constant strings to be used as a placeholder for expressions 318ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // that are not valid C++ syntax, but warn that they are ignored. 319ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Attr.getName(); 321ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 322ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins } 323ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins 3243ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 328b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 3303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 3313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 333b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 334b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 3363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 3373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 341ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 346b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 34783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, ArgTy); 348b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 350b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 352b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 353e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 354e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 355e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 356e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 3573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 3583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 3593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 3603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool pointer = false) { 363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 364fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 371b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 372fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 377fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 378fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer) 379768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 380fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 381768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 382fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 383fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 384db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 385b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool pointer = false) { 386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 388b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 389db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 394b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 397db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 398ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 400db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 401ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins SmallVector<Expr*, 1> Args; 402ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // check that all arguments are lockable objects 403ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 404ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins unsigned Size = Args.size(); 405ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size != 1) 406ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 407ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr *Arg = Args[0]; 408b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer) 410768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 4113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, Arg)); 412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 413768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 414db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 415db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 416db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool scoped = false) { 419fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4241748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski // FIXME: Lockable structs for C code. 425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedClass; 428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (scoped) 432768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 434768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 444b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 449fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 450768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 45471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D, 455ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 45671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany assert(!Attr.isInvalid()); 45771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 45871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!checkAttributeNumArgs(S, Attr, 0)) 45971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 46071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 46171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 46271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 46371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany << Attr.getName() << ExpectedFunctionOrMethod; 46471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 46571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany } 46671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 46771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), 46871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Context)); 46971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany} 47071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 471db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 472db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski bool before) { 473db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 475b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 476db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 478db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 479b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 480b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 482b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 486ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that this attribute only applies to lockable types. 487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 488b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 489b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 490b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 491ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 493b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 494b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 495b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 496b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 498ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that all arguments are lockable objects. 499ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 5003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 501ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 502ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 503ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 5043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 505db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (before) 506768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 508db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 509768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 511db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 512db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 513db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 514b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 515db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 516db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 519b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 520b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 521db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 528ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 5293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 532db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 533768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 5343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 537768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 5383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 540db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 545db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 546b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 547db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 549b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 551db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 556b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 2> Args; 562b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 563ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 5643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 568768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, 57069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 5713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 573768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 57469f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski S.Context, 57569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 57669f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski StartArg, Size)); 577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 583b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 585db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 586b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 594ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 596ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 597ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 598ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 601768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 6023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 605768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 6063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 608db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 609db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 614db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 616b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 624ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 6253ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 628768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 633b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 634db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 635db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 636b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 639db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 640b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 641db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 647b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 65083cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, Arg->getType()); 6513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 652768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg)); 653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 656b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 658db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 660db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 661db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 662b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 668b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 670ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 672ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 673ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 674ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 6753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 676768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 6773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 6821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 68387c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 684545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 685803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 686545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 6909cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 6929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6939cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 6949cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 695f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 696e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 697f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 698f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 6994ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 700e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, 701e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara false, false); 7024ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 7034ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 7044ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 7054ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 7079cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 7081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 7099cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 7101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 7117a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7139cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 7159cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 7169ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 7179cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 718ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 719a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 720bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 7229cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 7281731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 73187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 732768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 73387c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 738fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 73908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 7406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 741768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 7426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 7433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 74787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 748768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 749c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 750c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 751c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 752c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 7531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 75496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 7551731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 75696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 757bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 75863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 75987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 76063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 761768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 76263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 76363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 76463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7654ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 76663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 76763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 7692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // The IBOutlet/IBOutletCollection attributes only apply to instance 7702f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // variables or properties of Objective-C classes. The outlet must also 7712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // have an object reference type. 7722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 7732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 7740bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << VD->getType() << 0; 7762f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 781f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << PD->getType() << 1; 7832f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else { 7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 790f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return true; 7922f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek} 7932f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 7941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 79563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 7961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 79763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 7982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 7992f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 80063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 80163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 8022f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 80396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 80496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 8051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 8061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 807857e918a8a40deb128840308a318bf623d68295fTed Kremenek 808857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 809a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 810857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 811857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 812857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 813857e918a8a40deb128840308a318bf623d68295fTed Kremenek 8142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 815857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 8162f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 819f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian II = &S.Context.Idents.get("NSObject"); 8203a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 821b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 82287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 823a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 824a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 825a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 826a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 827b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 828a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 829a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 830a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 831a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 832f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 833a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 834a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 836f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 837f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis QT, Attr.getParameterLoc())); 838857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 839857e918a8a40deb128840308a318bf623d68295fTed Kremenek 840d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 84168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 84268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 84468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 84568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 84668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 84768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 84868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 84968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 85068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 85168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 85268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 8551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 85887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 860883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 86407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 86507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 86687c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 86787c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 868eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 869eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 8705f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 871bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 872eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 874bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 876eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 8777a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 878eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 879ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 880ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 881fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 882fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 883eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 884eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 885bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 886eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 889fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 89030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 891eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 892eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 894465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 89507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 89607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 89707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 89807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 89907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 90007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 90107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 90207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 90307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 904eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 905eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 90687c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 907d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 90868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 909dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 910eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 911c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 912fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 9137fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 914eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 915bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 916eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 917eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 918bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 9217fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 92287c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 92387c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 924d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 925dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 926d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 92746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 928bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 929ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 93060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 93160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 93260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 93360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 93460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 9357fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 93660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 937eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 9387fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 9397fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 9407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 942768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 944eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 945eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 9461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 951dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 952dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 9542a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 955dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 9632a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 9642a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 965cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 966dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9702a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9712a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 972cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 974dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 975dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 976dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9782a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 979cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 982dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9852a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9862a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 9872a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 9882a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 989dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 99187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 992883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 993883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 99707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 99807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 99987c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 100087c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10102a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 10112a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10137a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1020dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1022dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1023dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1025dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 103007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 103107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 103207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 103307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 103407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 103507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 103607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 103707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 103807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1040cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1041cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 104387c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1046dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1047cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1054cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 10577a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1059dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1066dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1069dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 107387c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 107487c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1075cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1076cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1077cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1078cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1079cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1080cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1081cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1084dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1085dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1088dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1089dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1090dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1093cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1094cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1095cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1097cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 109887c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1099cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1108332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1109332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1110332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1111332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1112332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1113332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 111911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 112011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 112211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 112311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 112411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 112511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 112611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 112711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 112887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1129332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1130883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1131332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1132332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1133332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 113487c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1135332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 114011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 114111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 114211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 114687c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 11477a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 11487a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1149332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 11507a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1171332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1172332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 11817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 118411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11855cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 1192768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1193f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1196768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 119711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1201545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 12023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1209bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12105cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1211fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 12123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1216bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1217f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1218f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1219f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1220f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1223768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1224f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 12291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1230dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1231dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 123287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1233dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1234883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1235dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1236dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1237dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 1238768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1239dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 12411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 12421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1243dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1244831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 12453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1246af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1247af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 12485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 124987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 12505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1251883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 12525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 12535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1254bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1255768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1256af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1257af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 12581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1259dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1260831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 126176168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 126276168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 126376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 126587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 12672cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1268768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 12692cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 12702cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1271fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1272fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 12732cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 127476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 127576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 12761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 127734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 12781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 127934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 128034c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 1281768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 128234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 128334c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 12841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 128556aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 128687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1287768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1288722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1289722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1290883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1291a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1292a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 12931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 129456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 129587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1296768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1297722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1298722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1299883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1300a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1301a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 13021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 130387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1305711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 130787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1309883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1315711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1317831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1318711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1319711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1321711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1324b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1325b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 13271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1328b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1329b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1330b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 1331b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 13331731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 1334b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 133587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 133687c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 13373ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 13383ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1339e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1340e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1341b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1342883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 134419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1346b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1347768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 13486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 135035cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 13511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 1355f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 1356f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1357f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1358f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1359f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 136735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 136935cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 137587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1377883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 137935cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 138187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 138335cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 138687c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 139101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 139201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1399f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1400f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 140101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 140201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1408768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 140935cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 141035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 14111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 141287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1414883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1416bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 14201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 142173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1422831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 14233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 142473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 142573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1426bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 142787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 142887c44604325578b8de07d768391c1c9432404f5aChandler Carruth !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 1429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1430883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 143173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 143273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1434768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 143573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 143673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 1437f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D, 1438f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola const AttributeList &Attr) { 1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola // check the attribute arguments. 1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (Attr.hasParameterOrArguments()) { 1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1443f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1444f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1445f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (!isa<FunctionDecl>(D)) { 1446f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1447f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola << Attr.getName() << ExpectedFunction; 1448f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola} 1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 14541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1455b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1456831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1460bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 146187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1462186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1464b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1465b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 146687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1468883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1470b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1472768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1473b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1474b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 14751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1477bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1478bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 14793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 14847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1486ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1487ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1488fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1494bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 149587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1496fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1497883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1501768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1502f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 15063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1507bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1508bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 15093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1510bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 15147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1516ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1517ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1518fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 15203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1524bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 152587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1526fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 15283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1531768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1532f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1536951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1538bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1539c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1540c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1541951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1542c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 15435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1544951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1545951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1546c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1547951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1548951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner << "deprecated"; 1549c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1550c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1551951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 15526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1553bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1554768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str)); 15556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1558951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1560bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1561bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1562bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1563951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1564c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 15655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1566951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1567951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1568c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1569951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), 1570c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1571c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1572c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1573951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 1574c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1575768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str)); 1576bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1577bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1578742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1579742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1580742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1581742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1582742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1583742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1584742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 1585742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1586742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis Attr.getRange(), S.Context)); 1588742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1589742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1590b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D, 1591b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard const AttributeList &Attr) { 1592b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!isa<ObjCInterfaceDecl>(D)) { 1593b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1594b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1595b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1596b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1597b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard unsigned NumArgs = Attr.getNumArgs(); 1598b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NumArgs > 0) { 1599b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1600b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1601b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1602b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1603b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); 1604b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard} 1605b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 160671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 1607e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian const AttributeList &Attr) { 1608341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian if (!isa<ObjCInterfaceDecl>(D)) { 1609341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 1610341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian return; 1611341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian } 1612341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian 1613e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1614e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian if (NumArgs > 0) { 1615e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1616e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian return; 1617e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian } 1618e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 161971207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( 1620e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian Attr.getRange(), S.Context)); 1621e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian} 1622e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 16231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D, 16241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor IdentifierInfo *Platform = Attr.getParameterName(); 16260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SourceLocation PlatformLoc = Attr.getParameterLoc(); 16270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (PlatformName.empty()) { 16310a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 16320a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << Platform; 16330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 16350a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16360a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 1640b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1642c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 16440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Deprecated.isValid() && 16453b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Deprecated.Version)) { 16460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << PlatformName << Deprecated.Version.getAsString() 16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16520a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Obsoleted.isValid() && 16533b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Obsoleted.Version)) { 16540a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16570a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Deprecated.isValid() && Obsoleted.isValid() && 16613b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Deprecated.Version <= Obsoleted.Version)) { 16620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 16630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << Deprecated.Version.getAsString(); 16650a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1668006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian StringRef Str; 1669006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian const StringLiteral *SE = 1670006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); 1671006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian if (SE) 1672006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str = SE->getString(); 1673006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian 1674768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context, 16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Platform, 16760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Introduced.Version, 16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Deprecated.Version, 1678b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor Obsoleted.Version, 1679006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian IsUnavailable, 1680006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str)); 16810a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 16820a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 16851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 16866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16887a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 16896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 16906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1691bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16925cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1693fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 16943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 16956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1697bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16985f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 1699cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1700bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1701c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1702cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1703c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1704cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1705c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1706cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 17074188760f6bb20f91c6883dffd89204419f852deeJohn McCall else if (TypeStr == "protected") { 17084188760f6bb20f91c6883dffd89204419f852deeJohn McCall // Complain about attempts to use protected visibility on targets 17094188760f6bb20f91c6883dffd89204419f852deeJohn McCall // (like Darwin) that don't support it. 17104188760f6bb20f91c6883dffd89204419f852deeJohn McCall if (!S.Context.getTargetInfo().hasProtectedVisibility()) { 17114188760f6bb20f91c6883dffd89204419f852deeJohn McCall S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 17124188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Default; 17134188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 17144188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Protected; 17154188760f6bb20f91c6883dffd89204419f852deeJohn McCall } 17164188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 171708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 17186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1720bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1721768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type)); 17226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 17236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 17251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1726d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1727d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 172887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1729883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 1730d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1731d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1732d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 173387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 173487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 173587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1736d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 1737d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 173887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 174087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 1741d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 17445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 1745d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 1746d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 1747d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 1750d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 1752d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 1754d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1756d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 1758d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 1759d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 176187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 1762d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1763d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1765f85e193739c953358c865005855253af4f68a497John McCall if (family == ObjCMethodFamilyAttr::OMF_init && 1766f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 1767f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 1768f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 1769f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 1770f85e193739c953358c865005855253af4f68a497John McCall return; 1771f85e193739c953358c865005855253af4f68a497John McCall } 1772f85e193739c953358c865005855253af4f68a497John McCall 1773768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 1774f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 1775d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 1776d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 17771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 17781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 17791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 17800db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 1781bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17820db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 17830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 17840db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 17850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 17860db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1788768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 17890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 17900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 17911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 1792fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 17932b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1794fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1795fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1796162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 1797fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1798fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 17996217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1800fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1801fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1802fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1803fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1804f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek else if (!isa<ObjCPropertyDecl>(D)) { 1805f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // It is okay to include this attribute on properties, e.g.: 1806f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 1807f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 1808f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 1809f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // In this case it follows tradition and suppresses an error in the above 1810f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // case. 18119b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 1812f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek } 1813768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 1814fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1815fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1816bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 18171b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1818f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 18192b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1820f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1821f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1822f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1823f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1824f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1825f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1826f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1827f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1828768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 1829f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1830f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 18311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1832bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1833fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 18343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 18359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18369eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1837bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 18393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18419eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1842bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1843cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 184492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 18459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 18469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1847fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 18483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 18499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1851bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1852768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 18539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 18549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 18551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1856770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1857770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1858bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1859770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1860bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1861bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18623323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned sentinel = 0; 1863770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 18647a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1865770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1866ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1867ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1868fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1870770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1871770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18733323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if (Idx.isSigned() && Idx.isNegative()) { 1874fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1876770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1877770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 18783323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall 18793323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall sentinel = Idx.getZExtValue(); 1880770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1881770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 18823323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned nullPos = 0; 1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 18847a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1885770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1886ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1887ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1888fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1890770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1891770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18943323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 1895770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1896770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1898fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1899770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1900770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1901770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 190387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 19043323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 1905897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1906897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1907897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1908897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1910897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 19113bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1912770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1913bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 191487c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 1915770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 19163bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1917770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 19182f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1919a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 1920a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman if (!BD->isVariadic()) { 1921a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 1922a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman return; 1923a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } 192487c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 19252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1926daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 192787c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 1928f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 19292f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 19303bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 19313bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 19322f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 19332f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1934ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 19352f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1936883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 19372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 19382f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1939770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1940fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1941883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1942770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1943770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1944768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 1945f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1946770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1947770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 19481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 1949026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 19501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1951026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1952026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1953f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1954026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1955883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 1956026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1957026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1958bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1959f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1960f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1961f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1962f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1963f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1964f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1965f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1966f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1967f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1968f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1969f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1970f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1971768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 1972026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1973026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 19741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 197687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 197787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 198187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 198213c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian if (isa<CXXRecordDecl>(D)) { 198313c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 198413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian return; 198513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian } 198687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 198787c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 1988f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1989f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1990f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 199187c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1992332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1993332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 1994332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 199587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 19966e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1998bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1999768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 20041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 20056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 20061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 20076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 20096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 20100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 20110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 20120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 20130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 20140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 2015def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2016bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 201790eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2018def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 2019def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 2020c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2021883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 20226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 20246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 20256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 2026768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 20276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 20286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D, 20301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 20316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 20321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 3)) 20336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 20346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 20356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 20366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 20377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 20386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 2039ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2040ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 20416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 20426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 20446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 20456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 20466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 2047768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 2048cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 20496f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 20506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 20516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 20521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 205317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 20541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 205517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 205617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 205717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 205817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 20597a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2060797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 206117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 2062797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 206317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 206417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 20651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2066797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 2067bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2068a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 2069a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2070a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 2071797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 2072797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 20731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2074a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 2075a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2076a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2077a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 2078a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 2079a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 2080768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context, 2081f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 208217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 208317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 20846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2087831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 20883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 20906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2091b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 209287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2093b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2094ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2095b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2096768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2097b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 20986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 21001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2101232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2102831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 21033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2104232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2105232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2106bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 210787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2108b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2109ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2110b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2111768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2112b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2113232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2114232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 21151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2116232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 21171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2118232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2119bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2120768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2121232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2122232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 21231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2125f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2126f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2127f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2128bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2129f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2130f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2131f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2132f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2133bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 213487c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2135bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2136f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2137f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2138f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2142c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2143f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2144f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2145f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2146f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2147f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2148f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2149f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2152f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2153f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2154f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2155f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2157f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2158f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2159f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2161f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2162f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2163f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2164f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2165f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 216789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 216889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 216989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 217089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2171b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2172b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2173f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 217489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 217589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 217689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 217789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2179768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 21805f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); 2181f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2182f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2183bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2184bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 21851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 21861731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 21875b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21881731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 218987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 21905b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2191883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21935b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 219407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 219507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 219607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 219787c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 219887c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 220007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 22015b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 22027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 22035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2204ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2205ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 22065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 22075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 22085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22095b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2210bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 22125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 22135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 22145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2218bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 221907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 222007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 222107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 222207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 222307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 222407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 222507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 222607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 222707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 22285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 222987c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 22325b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 22335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 22345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 22356217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 22365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 22375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 22395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2241bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 224287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 22445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 22466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 22475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 22485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2249bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 22505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 22515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2252bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2254768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 225507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 22565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 22575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 22582b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 22592b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 22602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 22612b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 22622b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 22633c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 22642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 22652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 22662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 22682b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 22695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 22712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 22732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 22742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 22752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 228069d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" || 2281cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "zcmn_err" || 2282cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "kprintf") // OpenBSD. 22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2285bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 2286bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 22873c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 22883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 22902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 22912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2292521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2293521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 22941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 22951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 22964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus) { 2297521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2298521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2299521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2300521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 230187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2302b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2303b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2304b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2305b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 230687c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2307b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2308b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2309b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2310b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2311b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2312b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2313b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2315521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2316521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2317521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2318521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2319521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 23207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 2321b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2322521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2323521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2324521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2325521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2326521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 23309f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2332521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2333521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2335521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2336521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2339521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2340521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2342bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 23431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 23446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2345545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2346fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 23473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 23486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2351545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 23523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 235687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2358883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 23596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 236207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 236307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 236487c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 236587c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 23712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 23722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 23732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 23742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 23752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 23763c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23773c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 23783c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 23793c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 238201eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 23836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 23877a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2388803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2389ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2390ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2391fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2397fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 23983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24054a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 24064a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 240707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 240807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 240907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 24104a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 24114a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 24124a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 24134a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 24141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 241687c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 24176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24182b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2419085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2420fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2421fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2422085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2423085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 24242b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2425390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2426390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2427803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2428390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2430fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 24316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2432bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 24346217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2435390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2436fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2437fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 24386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 24427a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2443803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2444ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2445ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2446fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 24473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 24486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 245387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 24546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 24556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 245687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 24576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 24623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 24632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 24646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 2465fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2466fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 2471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 24723c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 24736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2476b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // Check whether we already have an equivalent format attribute. 2477b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor for (specific_attr_iterator<FormatAttr> 247887c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<FormatAttr>(), 247987c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<FormatAttr>(); 2480b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor i != e ; ++i) { 2481b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor FormatAttr *f = *i; 2482b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getType() == Format && 2483b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFormatIdx() == (int)Idx.getZExtValue() && 2484b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFirstArg() == (int)FirstArg.getZExtValue()) { 2485b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // If we don't have a valid location for this attribute, adopt the 2486b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // location. 2487b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getLocation().isInvalid()) 2488ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis f->setRange(Attr.getRange()); 2489b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor return; 2490b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2491b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2492b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 2493768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format, 2494cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 24952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 24966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 24991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 25006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 25011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25050c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 25060c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 250787c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 25080c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 25090c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 25100c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 251187c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 25120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 25130c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 2514fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2515883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 25186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25195e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall if (!RD->isCompleteDefinition()) { 2520bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 25210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 25220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 25240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 252517945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 252617945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 25270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 25280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 25290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2531bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 25320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 25330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 253490cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2535bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 253690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 253790cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 25380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2540bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 25420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 25430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 25460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 25470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 25480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2549bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 2551bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 25520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 25530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 25540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 2555bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 25570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 2558bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 2559bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 2560bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 25616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2562768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 25636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 25666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 25671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 25686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 25707a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2571797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2572bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 25746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 25756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 2576797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 25776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 257977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 258077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Don't duplicate annotations that are already set. 258177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge for (specific_attr_iterator<AnnotateAttr> 258277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge i = D->specific_attr_begin<AnnotateAttr>(), 258377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 258477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge if ((*i)->getAnnotation() == SE->getString()) 258577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return; 258677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 2587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 2588f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 25896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 25926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2593545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 25943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 25956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2597bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 2599bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 2600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 26016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2602545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2603768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 26044ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 26054ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 26064ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2607768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 26084ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 26094ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2610768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 26110b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne // FIXME: Handle pack-expansions here. 26120b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne if (DiagnoseUnexpandedParameterPack(E)) 26130b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne return; 26140b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne 26154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 26164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 26186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2620bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2621768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis SourceLocation AttrLoc = AttrRange.getBegin(); 2622cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 262349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 2624282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith ExprResult ICE = 2625282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith VerifyIntegerConstantExpression(E, &Alignment, 2626282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith PDiag(diag::err_attribute_argument_not_int) << "aligned", 2627282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith /*AllowFold*/ false); 2628282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith if (ICE.isInvalid()) 262949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 2630396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 26314ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 26324ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2633396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2634396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2635396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2636282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take())); 2637cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2638cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2639768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2640cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2641cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2642768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2643cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 26446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2645fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2646d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 2647bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2649bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2650bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2651bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 26521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2654fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2655fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2656fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 26571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2658fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 26591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2661fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2662fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 26630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2664fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2666210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 26675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2669fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2670210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2671210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 267573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2676210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 267873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 267973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 268073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 268173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 268273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 268873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 268973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2694fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2695fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 2696fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 2698210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 2699bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2700210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 2701bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2704210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 2705bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2710162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2712fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2715fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2716768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << "mode" << Attr.getRange(); 2717fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 271973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2720183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 272173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 272273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 27232ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 272573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 272673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 272773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 272873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 272973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 273073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 273173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 273273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2733390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2734390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2735390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2736390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2737f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2738f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2739fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2740fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 27423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2744fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 27453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2746fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2747fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 274873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 274973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 275073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 275173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 27530b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2754fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2757fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 275873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 275973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 276173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2762fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 27630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2767fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2770fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 27710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2772fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2775fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2779bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2780aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2781aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2782aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2783fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2784bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2785aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2786aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2787aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 278973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 279073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 279173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2792f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2793f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2794f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2795f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2796f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2797f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2798f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2799f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2800f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 280173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2802fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2803fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 280473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 280573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2806fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2807fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2808fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2809162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2810ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2811a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2812ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2813fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2814fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 28150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 28161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2817d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 28181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2819d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2820e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 282187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 2822d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2823883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2824d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2825d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2827768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 2828d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2829d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 28301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 28315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 28321731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 28335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 28341731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2835bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 283687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 28375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2838883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 28395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 28405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2842768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 28435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 28445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 28451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 28461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 28477255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 28481731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 28497255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 28501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 28517255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 285287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 28537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2854883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 28557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 28567255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 28577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2858768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 2859f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 28607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 28617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 28621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2863ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2864ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2865831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 287087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2873ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2876768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 2877ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2884ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 289087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2892883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2894ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2896768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2904ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 290887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2910883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 291487c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 29152c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2916723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 29172c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 29182c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 29192c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 29202c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 29212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 29222c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 29232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 29242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 29252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 29262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 29272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 29282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2929768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 2930ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2931ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2932ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2933ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2934ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2936ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2937ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2939ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 29401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2941ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 294287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2944883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2947ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2948768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2950ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2952ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2956ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29571731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 29591731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2960ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 296187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2963883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2966ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2967768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2969ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2971ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2972ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 297426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 29751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 297626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 2977bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 297887c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2979c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 298026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2981883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 298226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 298326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2984bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29850130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2986cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2987c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2988c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2990768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 299126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 299226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 29931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 299487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 299687c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2997e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2998711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 299987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 3000711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3001e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 300287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 300387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 300487c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3005711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3006711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 300887c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3009e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 3010768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 3011e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3012e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 3013768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 3014e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3015f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 3016768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 301704633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 3018e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 3019768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 3020e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 302152fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 302352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 3024414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 302587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *Arg = Attr.getArg(0); 3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 30275cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 302887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3029414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 303087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3031414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3032414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3033414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 30345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3035414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 3036414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") 3037414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else if (StrRef == "aapcs-vfp") 3039414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 3040414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else { 304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3043414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3044414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 3046768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 3047414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3048e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 3049e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 3050e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 3051e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 3052e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 30531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 305456aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 3055768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 3056f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 3057f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 3058711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 3059711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3061711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3062831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if ((attr.getNumArgs() != 0 && 3063831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 3064831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek attr.getParameterName()) { 3065711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3066711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 3067711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3068ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 306955d3aaf9a537888734762170823daf750ea9036dEli Friedman 3070414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 3071414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 3072711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 3073711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 3074711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 3075711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 3076711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 3078414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 3079414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 3080414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 30815cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3083414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 3084414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 3085414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 3086414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3087414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 30885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3089414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 3090414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 3091414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3092414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 3093414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 3094414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3095414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3096414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // FALLS THROUGH 3097414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 30987530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("unexpected attribute kind"); 3099711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3100711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3101711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3102711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 31041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 310587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3107711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 310887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 311187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 311287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 311387c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3114ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3115ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 311655d3aaf9a537888734762170823daf750ea9036dEli Friedman 3117768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3119711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3120711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 312287c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 312387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3124711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3125711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 312687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 312887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3129711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3130711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3131711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 313287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 313355d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3134ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3135711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 313687c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 313755d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3139711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 314055d3aaf9a537888734762170823daf750ea9036dEli Friedman } 314155d3aaf9a537888734762170823daf750ea9036dEli Friedman 3142bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 314387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 314455d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 314587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3146711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 314755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 314855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3149711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3150bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 315187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3152bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 315387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3154711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 315555d3aaf9a537888734762170823daf750ea9036dEli Friedman } 315655d3aaf9a537888734762170823daf750ea9036dEli Friedman 3157711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3158ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3159ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 31601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 31617b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 31627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 31637b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3164bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3165bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 31667b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 316987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 31707b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3171883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 31727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 31767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 31777b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 31817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 31907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 3197768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 31987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 31997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 32037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 32050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3206b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3207b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3208b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3209c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 32106c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 32116c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isObjCObjectPointerType() || 32126c73a2975ba9112787380abd878876336957b3f6Douglas Gregor S.Context.isObjCNSObjectType(type); 3213c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3214c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 32156c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 32166c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isPointerType() || 32176c73a2975ba9112787380abd878876336957b3f6Douglas Gregor isValidSubjectOfNSAttribute(S, type); 3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3219c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 322187c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3222c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 322387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3224768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedParameter; 3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3227c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3228c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 322987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3231c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3232c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3236c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3237c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 323887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3239768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << cf; 3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3241c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3242c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 3244768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 3246768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 32501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 325187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 325287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3253768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedMethod; 3254c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3255c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3256c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3258c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3262b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3263c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 326587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 326787c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3268831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian returnType = PD->getType(); 32694e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 327087c44604325578b8de07d768391c1c9432404f5aChandler Carruth (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3271f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 327287c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3273c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 32745dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 327587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3276768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() 3277883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3278b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3279b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3280bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3281c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3282c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 328387c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 32847530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("invalid ownership attribute"); 3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3286c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 3287c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 3288c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3289c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3290c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3291c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3292c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 3294c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3295c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3296c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3298c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3299c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 330087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3301768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3302bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 33035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3304bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3306b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3307b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ownership attribute"); 3308c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3309768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3310c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3311c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 331231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3314f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 331531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 331631c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 3317768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3318f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 331931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 3320b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 3321768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3322f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3323b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3324b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3326f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3327b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3328b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3329b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3330b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3331dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3332dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3333dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3334dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3335dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3336dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 33370e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian if (!method || !isa<ObjCMethodDecl>(method)) { 33380e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3339f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 3340dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3341dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3342dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 3345f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian 3346f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian if (!resultType->isReferenceType() && 3347f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3348dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3349dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3350dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3351dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3353dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3354dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3355dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3356dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3357768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3358dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3359dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 33608dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer. 33618dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 33628dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!isa<FunctionDecl>(D)) { 33638dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3364f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << A.getRange() << A.getName() << ExpectedFunction; 33658dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 33698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Check whether there's a conflicting attribute already present. 33718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Attr *Existing; 33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFUnknownTransferAttr>(); 33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFAuditedTransferAttr>(); 33768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (Existing) { 33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getName() 33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << Existing->getRange(); 33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // All clear; add the attribute. 33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 33888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 33898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 33908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 33918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 33928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3395fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 3396fe98da0fa352462c02db037360788748f95466f7John McCall const AttributeList &Attr) { 3397fe98da0fa352462c02db037360788748f95466f7John McCall RecordDecl *RD = dyn_cast<RecordDecl>(D); 3398fe98da0fa352462c02db037360788748f95466f7John McCall if (!RD || RD->isUnion()) { 3399fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3400f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedStruct; 3401fe98da0fa352462c02db037360788748f95466f7John McCall } 3402fe98da0fa352462c02db037360788748f95466f7John McCall 3403fe98da0fa352462c02db037360788748f95466f7John McCall IdentifierInfo *ParmName = Attr.getParameterName(); 3404fe98da0fa352462c02db037360788748f95466f7John McCall 3405fe98da0fa352462c02db037360788748f95466f7John McCall // In Objective-C, verify that the type names an Objective-C type. 3406fe98da0fa352462c02db037360788748f95466f7John McCall // We don't want to check this outside of ObjC because people sometimes 3407fe98da0fa352462c02db037360788748f95466f7John McCall // do crazy C declarations of Objective-C types. 34084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (ParmName && S.getLangOpts().ObjC1) { 3409fe98da0fa352462c02db037360788748f95466f7John McCall // Check for an existing type with this name. 3410fe98da0fa352462c02db037360788748f95466f7John McCall LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 3411fe98da0fa352462c02db037360788748f95466f7John McCall Sema::LookupOrdinaryName); 3412fe98da0fa352462c02db037360788748f95466f7John McCall if (S.LookupName(R, Sc)) { 3413fe98da0fa352462c02db037360788748f95466f7John McCall NamedDecl *Target = R.getFoundDecl(); 3414fe98da0fa352462c02db037360788748f95466f7John McCall if (Target && !isa<ObjCInterfaceDecl>(Target)) { 3415fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 3416fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(Target->getLocStart(), diag::note_declared_at); 3417fe98da0fa352462c02db037360788748f95466f7John McCall } 3418fe98da0fa352462c02db037360788748f95466f7John McCall } 3419fe98da0fa352462c02db037360788748f95466f7John McCall } 3420fe98da0fa352462c02db037360788748f95466f7John McCall 3421fe98da0fa352462c02db037360788748f95466f7John McCall D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 3422fe98da0fa352462c02db037360788748f95466f7John McCall ParmName)); 3423fe98da0fa352462c02db037360788748f95466f7John McCall} 3424fe98da0fa352462c02db037360788748f95466f7John McCall 34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 34261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 342787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3428f85e193739c953358c865005855253af4f68a497John McCall 342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3430f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3431f85e193739c953358c865005855253af4f68a497John McCall} 3432f85e193739c953358c865005855253af4f68a497John McCall 34331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 34341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 343587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 343687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3437f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3438f85e193739c953358c865005855253af4f68a497John McCall return; 3439f85e193739c953358c865005855253af4f68a497John McCall } 3440f85e193739c953358c865005855253af4f68a497John McCall 344187c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 3442f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 3443f85e193739c953358c865005855253af4f68a497John McCall 3444f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 3445f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 344687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3447f85e193739c953358c865005855253af4f68a497John McCall << type; 3448f85e193739c953358c865005855253af4f68a497John McCall return; 3449f85e193739c953358c865005855253af4f68a497John McCall } 3450f85e193739c953358c865005855253af4f68a497John McCall 3451f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3452f85e193739c953358c865005855253af4f68a497John McCall 3453f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 3454f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 3455f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3456f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 3457f85e193739c953358c865005855253af4f68a497John McCall 3458f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 3459f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 3460f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 3461f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 3462f85e193739c953358c865005855253af4f68a497John McCall break; 3463f85e193739c953358c865005855253af4f68a497John McCall 3464f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 3465f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 3466f85e193739c953358c865005855253af4f68a497John McCall break; 3467f85e193739c953358c865005855253af4f68a497John McCall 3468f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 3469f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 347087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3471f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 3472f85e193739c953358c865005855253af4f68a497John McCall break; 3473f85e193739c953358c865005855253af4f68a497John McCall } 3474f85e193739c953358c865005855253af4f68a497John McCall 347587c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 3476768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3477f85e193739c953358c865005855253af4f68a497John McCall} 3478f85e193739c953358c865005855253af4f68a497John McCall 3479f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 34809428772f16e379bcad35254251f96e3d1077c730Aaron Ballman switch (Attr.getKind()) { 34819428772f16e379bcad35254251f96e3d1077c730Aaron Ballman default: 34829428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return false; 34839428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllimport: 34849428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllexport: 34859428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_uuid: 34869428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_deprecated: 34879428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noreturn: 34889428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_nothrow: 34899428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_naked: 34909428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noinline: 34919428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return true; 34929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman } 349311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 349411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 349511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 349611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 349711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 349811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 34991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 350062ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 350111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 35021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 350311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 35041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 350511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 350611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 35075cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3508d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3509d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 3510d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3511d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3512d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 35135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3514d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3515d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3516d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 3517f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 3518d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 3519d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3523d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 3524d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3525d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3526d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3527d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3528f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3529d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 35305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 3531f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 3532f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 3533f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 3534f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 3535d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 3536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3540d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 3541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3542d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3543d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3544d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 3545d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 354611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 3547768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 354811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 3549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 355011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3551f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 3552f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 3553b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 35540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 35550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 35560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 35571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 35581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 355960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 35601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 35611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 35621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 356360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 356460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 356560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 356660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 3567e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 35681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 35691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3570803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 3571e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_ibaction: handleIBAction(S, D, Attr); break; 3572e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutlet: handleIBOutlet(S, D, Attr); break; 3573e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutletcollection: 35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 3575803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 3576207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 3577ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 35786e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 35794211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 35804211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 3581bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 3582bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 3583803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 358460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 358560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 358660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 358760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 358860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 358960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 35901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 35911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3592bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 3594b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 35951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 35961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 35991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 36001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 36041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 36053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 36073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 36101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 36127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 36147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3620dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 3621dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 3622dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 36241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 36261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3629b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3630b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis case AttributeList::AT_objc_ownership: 36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 3632f85e193739c953358c865005855253af4f68a497John McCall case AttributeList::AT_objc_precise_lifetime: 36331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3634f85e193739c953358c865005855253af4f68a497John McCall 3635dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall case AttributeList::AT_objc_returns_inner_pointer: 3636dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3637dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3638fe98da0fa352462c02db037360788748f95466f7John McCall case AttributeList::AT_ns_bridged: 3639fe98da0fa352462c02db037360788748f95466f7John McCall handleNSBridgedAttr(S, scope, D, Attr); break; 3640fe98da0fa352462c02db037360788748f95466f7John McCall 36418dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_audited_transfer: 36428dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_unknown_transfer: 36438dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall handleCFTransferAttr(S, D, Attr); break; 36448dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3645b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 3646c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 36471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3648c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 36491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 3650c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3651c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 365231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 365331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3654b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3655b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 36561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 3657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3658e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_reqd_work_group_size: 36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleReqdWorkGroupSize(S, D, Attr); break; 36606f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 3661521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 36621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 3663521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 36641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 3665e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_ms_struct: handleMsStructAttr (S, D, Attr); break; 36661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 36671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3668e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_objc_arc_weak_reference_unavailable: 3669742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian handleArcWeakrefUnavailableAttr (S, D, Attr); 3670742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 3671b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard case AttributeList::AT_objc_root_class: 3672b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard handleObjCRootClassAttr(S, D, Attr); 3673b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard break; 367471207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek case AttributeList::AT_objc_requires_property_definitions: 367571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek handleObjCRequiresPropertyDefsAttr (S, D, Attr); 3676e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian break; 36771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 3678f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola case AttributeList::AT_returns_twice: 3679f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola handleReturnsTwiceAttr(S, D, Attr); 3680f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola break; 36811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 36821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 36831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3684026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 36851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 36861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 36871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3688803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 3690803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 36910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 36921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 36930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 3694d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 36951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 3696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 3697e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_NSObject: handleObjCNSObject (S, D, Attr); break; 36981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 36991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 37001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 37021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 37031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 37041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 37051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3706bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 370705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 370805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 37097255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 37101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 37117255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 371204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 371304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 371404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 3715f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 371652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3717414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: 37181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 371904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 3720f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 37211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 3722f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 372311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 37241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 372511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 3726fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3727fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 3728fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_guarded_var: 3729fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 3730fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3731fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_pt_guarded_var: 3732fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3733fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3734fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_scoped_lockable: 3735fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr, /*scoped = */true); 3736fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 373771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany case AttributeList::AT_no_address_safety_analysis: 373871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany handleNoAddressSafetyAttr(S, D, Attr); 373971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany break; 3740fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_no_thread_safety_analysis: 3741fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 3742fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3743fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_lockable: 3744fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 3745fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3746db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_guarded_by: 3747db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 3748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_pt_guarded_by: 3750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3751db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3752db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_lock_function: 3753db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3754db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3755db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_locks_required: 3756db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3757db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_trylock_function: 3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_lock_returned: 3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_locks_excluded: 3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_lock_function: 3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr); 3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_locks_required: 3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr); 3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_trylock_function: 3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr); 3775db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3776db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_unlock_function: 3777db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 3778db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3779db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_before: 3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_after: 3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3785fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3786803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 378782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 378882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 378982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 37907d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 37917d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 3792803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 3793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3794803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3795803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 379660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 379760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 379860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 379960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 38001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 38011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 380260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 380360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 380460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 380560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 380660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 380760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 380860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 380960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 38111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 381260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 381360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 38141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 381560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 381660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 3817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 3819f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 382060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 382160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 382211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 38231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 382411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 382511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 382611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 382711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 382811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 382960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 383011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3831dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 383211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 3833803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3834803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3835803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 38365f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access 38375f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier. 38385f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 38395f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen const AttributeList *AttrList) { 38405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen for (const AttributeList* l = AttrList; l; l = l->getNext()) { 38415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (l->getKind() == AttributeList::AT_annotate) { 38425f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen handleAnnotateAttr(*this, ASDecl, *l); 38435f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } else { 38445f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 38455f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return true; 38465f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 38475f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 38485f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 38495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return false; 38505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen} 38515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 3852e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it 3853e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about. 3854e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 3855e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for ( ; A; A = A->getNext()) { 3856e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall // Only warn if the attribute is an unignored, non-type attribute. 3857e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->isUsedAsTypeAttr()) continue; 3858e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::IgnoredAttribute) continue; 3859e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3860e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::UnknownAttribute) { 3861e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 3862e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3863e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } else { 3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3870e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being 3871e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes 3872e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it. 3873e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 3874e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 3875e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getAttributes()); 3876e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 3877e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 3878e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3879e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3880e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3881e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 3882900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3883900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 38847b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3885e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 3886e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3887900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 3888900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 3889900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 3890900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 3891900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 3892900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3893900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 3894900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 3896900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 3897900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 3898900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 3902c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3904900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 3905900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 3906900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 3907900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3908900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 3909900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3910900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 3911900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3912900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 3913900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 3914900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 39154278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie NewFD->setParams(Params); 3916b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3917e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3918e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3919ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 3920a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 392116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 392216573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 3923b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 3924b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 3925c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 3926b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3927e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3928e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 3929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 3931e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3932e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 39337b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3934c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 3935c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 3936c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3937c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 3938900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3939cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3940cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 3941cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3942c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 3943c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3944c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 3945c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 3946c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 3947c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 3948c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 3949c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 3950cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3951e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3952e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3953e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 39540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 39550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 39560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 395760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 395860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 3959d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 3960d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 396131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 396231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 396331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 396431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 396531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 396631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 396731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 396831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 396931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 397031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 397131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 397231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 3973d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 3974e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3975e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3976e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3977e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 39780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 39797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 398060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3981bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 39820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 39830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 39840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 39850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 39860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 39870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 398860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 39900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 39910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 399260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 39930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 399454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3995f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 3996f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 3997f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 3998f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 3999f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 4000a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian // Function declarations in sys headers will be marked unavailable. 4001a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 4002a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian !isa<FunctionDecl>(decl)) 4003f85e193739c953358c865005855253af4f68a497John McCall return false; 4004f85e193739c953358c865005855253af4f68a497John McCall 4005f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 4006f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 4007f85e193739c953358c865005855253af4f68a497John McCall} 4008f85e193739c953358c865005855253af4f68a497John McCall 4009f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 4010f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 4011f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 4012f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 4013f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 4014f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 4015f85e193739c953358c865005855253af4f68a497John McCall return; 4016f85e193739c953358c865005855253af4f68a497John McCall } 40174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount) 4018175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 4019175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // FIXME. we may want to supress diagnostics for all 4020175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // kind of forbidden type messages on unavailable functions. 4021175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (FD->hasAttr<UnavailableAttr>() && 4022175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.getForbiddenTypeDiagnostic() == 4023175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag::err_arc_array_param_no_ownership) { 4024175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.Triggered = true; 4025175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian return; 4026175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4027175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4028f85e193739c953358c865005855253af4f68a497John McCall 4029f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 4030f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 4031f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 4032f85e193739c953358c865005855253af4f68a497John McCall} 4033f85e193739c953358c865005855253af4f68a497John McCall 4034eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the 4035eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type. 4036eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 4037eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize <= StackCapacity); 4038eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4039eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Grow the stack if necessary. 4040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackSize == StackCapacity) { 4041eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall unsigned newCapacity = 2 * StackCapacity + 2; 4042eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 4043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall const char *oldBuffer = (const char*) Stack; 4044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4045eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackCapacity) 4046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall delete[] oldBuffer; 4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 4050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall StackCapacity = newCapacity; 4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall } 4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize < StackCapacity); 4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall new (&Stack[StackSize++]) DelayedDiagnostic(diag); 405554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 405654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 4058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Decl *decl) { 4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics &DD = S.DelayedDiagnostics; 406054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Check the invariants. 4062eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.StackSize >= state.SavedStackSize); 4063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(state.SavedStackSize >= DD.ActiveStackBase); 4064eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.ParsingDepth > 0); 406554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Drop the parsing depth. 4067eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.ParsingDepth--; 406854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // If there are no active diagnostics, we're done. 4070eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DD.StackSize == DD.ActiveStackBase) 4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return; 407258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 40732f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 40742f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 4075e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (decl) { 4076eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // We emit all the active diagnostics, not just those starting 4077eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // from the saved state. The idea is this: we get one push for a 40782f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 40792f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 40802f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 40812f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 40822f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 4083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 4084eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostic &diag = DD.Stack[i]; 4085eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 40862f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 40872f514480c448708ec382a684cf5e035d3a827ec8John McCall 4088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 40892f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 4090e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall // Don't bother giving deprecation diagnostics if the decl is invalid. 4091e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (!decl->isInvalidDecl()) 4092e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall S.HandleDelayedDeprecationCheck(diag, decl); 40932f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 40942f514480c448708ec382a684cf5e035d3a827ec8John McCall 40952f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 4096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedAccessCheck(diag, decl); 40972f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 4098f85e193739c953358c865005855253af4f68a497John McCall 4099f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 4100f85e193739c953358c865005855253af4f68a497John McCall handleDelayedForbiddenType(S, diag, decl); 4101f85e193739c953358c865005855253af4f68a497John McCall break; 410254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 410354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 410454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 410554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 410658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 4107eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 410829233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor DD.Stack[i].Destroy(); 410958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 4110eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.StackSize = state.SavedStackSize; 41112f514480c448708ec382a684cf5e035d3a827ec8John McCall} 41122f514480c448708ec382a684cf5e035d3a827ec8John McCall 41132f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 41142f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 41150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 41162f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 4117c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // A category implicitly has the availability of the interface. 4118c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 4119c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis return CatD->getClassInterface()->isDeprecated(); 41202f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 41212f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 41222f514480c448708ec382a684cf5e035d3a827ec8John McCall} 41232f514480c448708ec382a684cf5e035d3a827ec8John McCall 41249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 41252f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 41262f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 41272f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 41282f514480c448708ec382a684cf5e035d3a827ec8John McCall 41292f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 4130ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 4131c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 4132ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 4133ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 4134b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian else if (DD.getUnknownObjCClass()) { 4135b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_fwdclass_message) 4136b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian << DD.getDeprecationDecl()->getDeclName(); 4137b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class); 4138b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian } 4139c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 4140c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 4141ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 414254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 414354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 41445f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 41458e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 414689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 414754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 4148eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 4149b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 4150b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian UnknownObjCClass, 4151b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Message)); 415254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 415354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 415454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 415554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 41563a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 415754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 4158ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 4159c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 4160c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 41618e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 4162743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 41638e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 416489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian else { 41658e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 416689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 416789ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian } 41688e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 416954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 4170