SemaDeclAttr.cpp revision 79747e00e9f6b13b56e91462982d2456d0d9128f
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 31679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 31779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // Ignore empty strings without warnings 31879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (StrLit->getLength() == 0) 31979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins continue; 32079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 321ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // We allow constant strings to be used as a placeholder for expressions 322ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // that are not valid C++ syntax, but warn that they are ignored. 323ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 324ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Attr.getName(); 325ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 326ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins } 327ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins 3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 33079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // A pointer to member expression of the form &MyClass::mu is treated 33179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // specially -- we need to look at the type of the member. 33279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 33379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UOp->getOpcode() == UO_AddrOf) 33479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 33579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DRE->getDecl()->isCXXInstanceMember()) 33679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins ArgTy = DRE->getDecl()->getType(); 33779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 3393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 3423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 3433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 346b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 347b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 3483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 3503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 351b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 352b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 353ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 354b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 3553ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 356b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 357b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 358b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 35983cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, ArgTy); 360b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 362b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 363b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 364b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 365e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 366e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 367e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 368e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 3693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 3703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 3713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 3723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 374fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool pointer = false) { 375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 377fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 378fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 379fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 380fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 381fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 382fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 383b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 384fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 385fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 386fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 387ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 388fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 389fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 390fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer) 391768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 392fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 393768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 394fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 395fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 396db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool pointer = false) { 398db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 399db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 401db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 402db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 403db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 405db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 406b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 407db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 408db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 410ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 412db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 413ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins SmallVector<Expr*, 1> Args; 414ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // check that all arguments are lockable objects 415ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 416ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins unsigned Size = Args.size(); 417ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size != 1) 418ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 419ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr *Arg = Args[0]; 420b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 421db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer) 422768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 4233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, Arg)); 424db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 425768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 426db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 427db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 428db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool scoped = false) { 431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4361748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski // FIXME: Lockable structs for C code. 437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedClass; 440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (scoped) 444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 449fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 450fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 451fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 452fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 453fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 454fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 455fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 456b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 457fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 458fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 459fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 460fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 461fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 462768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 463fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 464fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 465fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 46671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D, 467ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 46871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany assert(!Attr.isInvalid()); 46971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 47071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!checkAttributeNumArgs(S, Attr, 0)) 47171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 47271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 47371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 47471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 47571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany << Attr.getName() << ExpectedFunctionOrMethod; 47671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 47771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany } 47871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 47971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), 48071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Context)); 48171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany} 48271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 483db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski bool before) { 485db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 486db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 487b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 488db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 489db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 491b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 492b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 493db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 494b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 498ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that this attribute only applies to lockable types. 499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 500b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 501b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 502b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 503ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 504b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 506b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 507b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 508b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 510ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that all arguments are lockable objects. 511ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 5123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 513ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 514ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 515ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 5163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 517db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (before) 518768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 5193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 520db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 521768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 5223ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 525db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 526b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 528db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 532b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 540ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 5413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5423ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5433ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 544db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 545768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 5463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 549768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 553db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 554db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 556db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 559db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 560db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 565db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 567b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 568b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 569b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 570b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 571b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 572b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5733ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 2> Args; 574b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 575ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 5763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 579db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 580768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 5813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, 58269f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 584db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 585768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 58669f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski S.Context, 58769f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 58869f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski StartArg, Size)); 589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 591db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 592b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 593db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 595b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 598b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 602db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 604b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 606ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 6073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 608ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 609ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 610ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 6113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 613768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 6183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 622db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 625db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 627db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 628b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 629db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 634b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 636ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 6373ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 640768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 6413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 6503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 659b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 660b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6613ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 66283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, Arg->getType()); 6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 664768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg)); 665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 668b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 671b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 672db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 674b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 676db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 680b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 682ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 6833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 684ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 685ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 686ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 6873ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 688768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 6893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 691db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 692db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 6941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 69587c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 696545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 697803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 698545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 700bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7059cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 707f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 708e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 709f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 710f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 7114ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 712e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, 713e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara false, false); 7144ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 7154ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 7164ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 7174ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 7189cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 7199cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 7201731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 7219cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 7221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 7237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7259cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7269cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 7279cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 7289ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 7299cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 730ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 731a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7339cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 7349cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 7396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 7401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 7416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 742bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 74387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 744768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 74587c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 7476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 7486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 749803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 75108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 7526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 753768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 7553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 75987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 760768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 761c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 762c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 763c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 764c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 7651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 76696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 7671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 76896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 769bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 77063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 77187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 77263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 773768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 77463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 77563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 77663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7774ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 77863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 77963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // The IBOutlet/IBOutletCollection attributes only apply to instance 7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // variables or properties of Objective-C classes. The outlet must also 7832f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // have an object reference type. 7842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 7852f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 7860bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << VD->getType() << 0; 7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7892f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7902f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 7922f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 793f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7942f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << PD->getType() << 1; 7952f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7962f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7972f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7982f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else { 7992f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 8002f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 8012f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 802f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 8032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return true; 8042f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek} 8052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 8061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 80763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 8081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 80963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 8102f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 8112f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 81263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 81363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 8142f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 81596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 81696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 8171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 8181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 819857e918a8a40deb128840308a318bf623d68295fTed Kremenek 820857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 821a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 822857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 823857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 824857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 825857e918a8a40deb128840308a318bf623d68295fTed Kremenek 8262f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 827857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 8282f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 829a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 830a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 831f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian II = &S.Context.Idents.get("NSObject"); 8323a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 833b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 83487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 835a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 836a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 837a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 838a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 839b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 840a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 841a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 842a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 843a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 844f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 845a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 846a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 847a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 848f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 849f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis QT, Attr.getParameterLoc())); 850857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 851857e918a8a40deb128840308a318bf623d68295fTed Kremenek 852d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 85368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 85468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 85568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 85668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 85768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 85868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 85968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 86068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 86168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 86268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 86368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 86468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 86568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 86668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 8671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 868bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 869bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 87087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 872883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 874eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 87607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 87707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 87887c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 87987c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 880eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 8825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 883bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 884eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 885eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 886bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 887bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 888eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 8897a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 890eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 891ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 892ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 893fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 894fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 895eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 896eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 897bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 898eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 899bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 900eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 90230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 903eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 904eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 906465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 90707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 90807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 90907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 91007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 91107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 91207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 91307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 91407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 91507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 916eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 917eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 91887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 919d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 92068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 921dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 922eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 923c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 924fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 9257fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 928eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 929eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 930bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 931bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 932bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 9337fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 93487c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 93587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 936d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 937dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 938d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 93946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 940bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 941ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 94260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 94360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 94460acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 94560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 94660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 9477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 94860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 949eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 9507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 9517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 9527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 953dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 954768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 955cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 956eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 957eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 9581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 959dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 960dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 961dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 9652a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 967dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 974cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 9752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 9762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 977cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 980dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 981dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9822a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9832a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 984cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 986dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 987dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 988dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9892a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9902a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 991cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9972a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 9992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 10002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1002dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 1004883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 1005883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 100907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 101007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 101187c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 101287c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 1019dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10205f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 1021dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 10232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 1024dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10257a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 1026dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1027dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1029dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1030dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1032dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1036dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 104207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 104307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 104407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 104507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 104607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 104707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 104807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 104907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 105007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1052cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1053cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 105587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1058dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1059cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1063dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1064dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1065dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1067dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1068dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 10697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1070dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1071dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1072dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1083dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 108587c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 108687c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1087cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1089cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1091cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1092cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1093cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1098dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1099dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1104cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1105cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1106cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1107cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1108dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1109cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 111087c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1111cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1112dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1113dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1114332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1115332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1116332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1117332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1118332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1119332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1120332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1122332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1123332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1125332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1126332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1127332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1128332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1129332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1130332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 113811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 113911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 114087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1141332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1142883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1143332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1144332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1145332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 114687c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1147332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 115887c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 11597a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 11607a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1161332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 11627a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 116311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 116411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 117311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 117711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1183332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1184332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 118511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 118811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 119111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 119211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 11937a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 119411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 119511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 119611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11975cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 119811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 119911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 120011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 120111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 120211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 120311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 1204768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1205f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 120611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 120711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1208768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 120911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 121011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 12111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1213545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 12143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1217bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 12206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1221bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1223fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 12243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 12256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1227bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1228bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1229f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1230f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1231f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1232f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 12336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1234bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1235768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1236f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1240dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 12411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1242dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1243dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 124487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1245dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1246883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1247dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1248dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1249dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 1250768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1251dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1252dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 12531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 12541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1255dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1256831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 12573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1258af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1259af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 12605bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 126187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 12625bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1263883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 12645bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 12655bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1266bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1267768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1268af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1269af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 12701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1271dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1272831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 127376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 127476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 127576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 127787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 12781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 12792cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1280768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 12812cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 12822cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1283fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1284fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 12852cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 128676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 128776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 12881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 128934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 12901731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 129134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 129234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 1293768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 129434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 129534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 12961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 129756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 129887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1299768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1300722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1301722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1302883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1303a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1304a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 13051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 130656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 130787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1308768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1309722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1310722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1311883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1312a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1313a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 13141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 131587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1316711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1317711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1318711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 131987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1320711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1321883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1322711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1323711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1324711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1326711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1327711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1328711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1329831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1330711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1331711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1332711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1333711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1334711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1335711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1336b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1337b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 13391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1340b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1341b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1342b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 1343b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 13451731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 1346b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 134787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 134887c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 13493ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 13503ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1351e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1352e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1353b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1354883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1355b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 135619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 13576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1358b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1359768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 13606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 13631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 1367f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 1368f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1369f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1370f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1371f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 137335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 137735cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 137835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 137935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 138035cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 138135cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 138235cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 138335cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 138435cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 138535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 138635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 138787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 138835cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1389883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 139035cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 139135cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 139235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 139387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 139435cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 139535cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 139635cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 139735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 139887c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 140001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 140101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 140201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 140301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 140401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 140501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 140601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 140701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 140801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 140901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 141001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1411f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1412f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 141301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 141401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 141501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 141601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 141701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 141801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 141901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1420768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 142135cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 142235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 14231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 142487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1426883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 14321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 143373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1434831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 14353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 143673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 143773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1438bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 143987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 144087c44604325578b8de07d768391c1c9432404f5aChandler Carruth !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 1441fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1442883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 144373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 144473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 144773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 144873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 1449f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D, 1450f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola const AttributeList &Attr) { 1451f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola // check the attribute arguments. 1452f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (Attr.hasParameterOrArguments()) { 1453f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1454f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1455f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1456f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1457f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (!isa<FunctionDecl>(D)) { 1458f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1459f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola << Attr.getName() << ExpectedFunction; 1460f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1461f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1462f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1463f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1464f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola} 1465f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 14661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1468831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1470b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1471b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1472bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 147387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1474186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1475b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1477b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 147887c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1479b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1480883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1481b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1482b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1485b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1486b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 14871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1489bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1490bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1492bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 14953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 14967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 14973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1498ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1499ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1500fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 15023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 15053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1506bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 150787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1508fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1509883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 15103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1513768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1514f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 15183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1519bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1520bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1522bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 15253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 15267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 15273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1528ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1529ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1530fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 15323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 15353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1536bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 153787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1538fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1539883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 15403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1544f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1548951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1549951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1550bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1551c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1552c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1553951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1554c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 15555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1556951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1557951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1558c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1560951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner << "deprecated"; 1561c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1562c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1563951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 15646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1565bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1566768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str)); 15676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1570951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1571951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1572bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1573bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1574bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1575951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1576c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 15775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1578951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1579951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1580c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1581951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), 1582c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1583c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1584c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1585951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 1586c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str)); 1588bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1589bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1590742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1591742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1592742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1593742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1594742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1595742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1596742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 1597742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1598742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1599768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis Attr.getRange(), S.Context)); 1600742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1601742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1602b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D, 1603b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard const AttributeList &Attr) { 1604b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!isa<ObjCInterfaceDecl>(D)) { 1605b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1606b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1607b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1608b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1609b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard unsigned NumArgs = Attr.getNumArgs(); 1610b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NumArgs > 0) { 1611b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1612b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1613b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1614b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1615b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); 1616b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard} 1617b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 161871207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 1619e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian const AttributeList &Attr) { 1620341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian if (!isa<ObjCInterfaceDecl>(D)) { 1621341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 1622341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian return; 1623341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian } 1624341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian 1625e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1626e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian if (NumArgs > 0) { 1627e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1628e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian return; 1629e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian } 1630e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 163171207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( 1632e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian Attr.getRange(), S.Context)); 1633e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian} 1634e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 16351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D, 16361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 16370a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor IdentifierInfo *Platform = Attr.getParameterName(); 16380a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SourceLocation PlatformLoc = Attr.getParameterLoc(); 16390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 16410a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 16420a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (PlatformName.empty()) { 16430a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 16440a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << Platform; 16450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 16470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 16500a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 16510a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 1652b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 16530a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1654c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 16550a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 16560a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Deprecated.isValid() && 16573b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Deprecated.Version)) { 16580a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << PlatformName << Deprecated.Version.getAsString() 16600a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16610a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16620a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Obsoleted.isValid() && 16653b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Obsoleted.Version)) { 16660a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16680a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16690a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16700a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16710a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16720a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Deprecated.isValid() && Obsoleted.isValid() && 16733b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Deprecated.Version <= Obsoleted.Version)) { 16740a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 16750a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << Deprecated.Version.getAsString(); 16770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16790a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1680006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian StringRef Str; 1681006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian const StringLiteral *SE = 1682006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); 1683006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian if (SE) 1684006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str = SE->getString(); 1685006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian 1686768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context, 16870a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Platform, 16880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Introduced.Version, 16890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Deprecated.Version, 1690b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor Obsoleted.Version, 1691006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian IsUnavailable, 1692006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str)); 16930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 16940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 16971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 16986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 17016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 17026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1703bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17045cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1705fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 17063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 17076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 1711cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1712bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1713c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1714cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1715c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1716cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1717c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1718cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 17194188760f6bb20f91c6883dffd89204419f852deeJohn McCall else if (TypeStr == "protected") { 17204188760f6bb20f91c6883dffd89204419f852deeJohn McCall // Complain about attempts to use protected visibility on targets 17214188760f6bb20f91c6883dffd89204419f852deeJohn McCall // (like Darwin) that don't support it. 17224188760f6bb20f91c6883dffd89204419f852deeJohn McCall if (!S.Context.getTargetInfo().hasProtectedVisibility()) { 17234188760f6bb20f91c6883dffd89204419f852deeJohn McCall S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 17244188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Default; 17254188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 17264188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Protected; 17274188760f6bb20f91c6883dffd89204419f852deeJohn McCall } 17284188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 172908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 17306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 17316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1733768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type)); 17346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 17356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 17361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 17371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1738d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1739d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 174087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1741883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 1742d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1743d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1744d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 174587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 174687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 174787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1748d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 1749d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 175087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1751d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 175287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 1753d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1754d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1755d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 17565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 1757d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 1758d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 1759d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 1760d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 1761d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 1762d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 1763d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 1764d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 1765d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 1766d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 1767d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1768d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 1769d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 1770d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 1771d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 1772d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 177387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 1774d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1775d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1776d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1777f85e193739c953358c865005855253af4f68a497John McCall if (family == ObjCMethodFamilyAttr::OMF_init && 1778f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 1779f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 1780f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 1781f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 1782f85e193739c953358c865005855253af4f68a497John McCall return; 1783f85e193739c953358c865005855253af4f68a497John McCall } 1784f85e193739c953358c865005855253af4f68a497John McCall 1785768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 1786f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 1787d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 1788d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 17891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 17901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 17911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 17920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 1793bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17940db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 17950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 17960db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 17970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 17980db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1799bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1800768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 18010db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 18020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 18031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 1804fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 18052b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1806fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1807fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1808162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 1809fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1810fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 18116217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1812fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1813fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1814fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1815fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1816f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek else if (!isa<ObjCPropertyDecl>(D)) { 1817f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // It is okay to include this attribute on properties, e.g.: 1818f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 1819f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 1820f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 1821f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // In this case it follows tradition and suppresses an error in the above 1822f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // case. 18239b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 1824f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek } 1825768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 1826fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1827fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1828bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 18291b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1830f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 18312b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1832f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1833f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1834f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1835f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1836f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1837f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1838f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1839f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1840768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 1841f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1842f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 18431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1844bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1845fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 18463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 18479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 18513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 18529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1854bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1855cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 185692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 18579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 18589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 18603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 18619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 18629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1864768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 18659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 18669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 18671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1868770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1869770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1870bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1871770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1872bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1873bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18743323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned sentinel = 0; 1875770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 18767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1877770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1878ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1879ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1880fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1882770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1883770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1884bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18853323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if (Idx.isSigned() && Idx.isNegative()) { 1886fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1887fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1888770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1889770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 18903323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall 18913323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall sentinel = Idx.getZExtValue(); 1892770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1893770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 18943323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned nullPos = 0; 1895770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 18967a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1897770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1898ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1899ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1900fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 19013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1902770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1903770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1904770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1905bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19063323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 1907770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1908770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1909fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1910fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1911770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1912770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1913770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1914770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 191587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 19163323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 1917897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1918897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1919897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1920897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1921bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1922897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 19233bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1924770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1925bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 192687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 1927770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 19283bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1929770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 19302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1931a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 1932a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman if (!BD->isVariadic()) { 1933a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 1934a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman return; 1935a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } 193687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 19372f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1938daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 193987c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 1940f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 19412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 19423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 19433bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 19442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 19452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1946ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 19472f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1948883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 19492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 19502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1951770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1952fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1953883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1954770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1955770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1956768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 1957f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1958770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1959770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 19601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 1961026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 19621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1963026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1964026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1965f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1966026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1967883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 1968026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1969026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1970bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1971f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1972f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1973f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1974f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1975f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1976f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1977f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1978f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1979f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1980f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1981f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1982f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1983768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 1984026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1985026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 19861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 198887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 198987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 199387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 199413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian if (isa<CXXRecordDecl>(D)) { 199513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 199613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian return; 199713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian } 199887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 199987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 2000f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 2001f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 2002f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 200387c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 2004332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 2005332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 2006332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 200787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 20086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 20096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 2010bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2011768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 20126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 20161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 20176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 20181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 20196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 20216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 20220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 20230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 20240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 20250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 20260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 2027def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2028bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 202990eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2030def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 2031def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 2032c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2033883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 20346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 20366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 20376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 2038768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 20396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 20406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 20411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D, 20421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 20436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 20441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 3)) 20456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 20466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 20476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 20486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 20497a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 20506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 2051ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2052ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 20536f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 20546f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 20556f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 20566f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 20576f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 20586f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 2059768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 2060cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 20616f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 20626f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 20636f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 20641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 206517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 20661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 206717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 206817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 206917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 207017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 20717a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2072797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 207317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 2074797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 207517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 207617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 20771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2078797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 2079bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2080a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 2081a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2082a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 2083797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 2084797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 20851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2086a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 2087a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2088a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2089a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 2090a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 2091a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 2092768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context, 2093f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 209417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 209517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 20966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2099831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 21003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 21016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 21026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2103b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 210487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2105b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2106ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2107b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2108768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2109b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 21106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 21116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 21121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2113232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2114831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 21153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2116232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2117232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 211987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2120b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2121ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2122b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2123768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2124b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2125232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2126232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 21271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2128232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 21291731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2130232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2131bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2132768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2133232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2134232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 21351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2136bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2137f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2138f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2139f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2141f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2142f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2143f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2144f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 214687c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2148f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2149f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2150f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2151f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2152bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2153f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2154c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2155f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2156f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2157f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2158f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2159f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2160f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2161f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2162f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2163bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2164f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2165f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2166f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2167f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2168f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2169f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2170f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2171f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2172f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2173f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2174f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2175f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2176f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2177f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 217989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 218089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 218189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 218289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2183b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2184b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2185f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 218689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 218789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 218889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 218989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2191768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 21925f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); 2193f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2194f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2195bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2196bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 21971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 21981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 21995b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 220187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 22025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2203883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 22045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 220607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 220707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 220807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 220987c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 221087c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 22115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 221207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 22135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 22147a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 22155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2216ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2217ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 22185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 22195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 22205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22215b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2222bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 22245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 22255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 22265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 22275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2228bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2230bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 223107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 223207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 223307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 223407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 223507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 223607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 223707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 223807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 223907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 22405b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 224187c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2242bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 22435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 22445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 22455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 22465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 22476217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 22485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 22495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 22515b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 22525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2253bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 225487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 22555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 22565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 22575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 22586217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 22595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 22605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2261bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 22625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 22635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2264bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2266768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 226707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 22685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 22695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 22702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 22712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 22722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 22732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 22742b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 22753c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 22762b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 22772b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 22782b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22792b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 22802b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 22815f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 22822b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 22832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 22842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 22852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 22862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 22872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 22882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 22892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22902b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 22912b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 229269d53845c68a4f01920b58ba6ce507d78220689cJean-Daniel Dupas Format == "strfmon" || Format == "cmn_err" || Format == "vcmn_err" || 2293cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "zcmn_err" || 2294cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "kprintf") // OpenBSD. 22952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 22962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2297bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 2298bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 22993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 23003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 23022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 23032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2304521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2305521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 23061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 23071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 23084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus) { 2309521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2310521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2311521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2312521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 231387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2314b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2315b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2316b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2317b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 231887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2319b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2320b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2321b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2322b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2323b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2324b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2325b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 2326b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2327521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2328521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2329521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2330521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2331521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 23327a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 2333b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2334521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2335521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2336521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2337521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2338521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2339521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2340521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2341521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 23429f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2343521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2344521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2345521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2346521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2347521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2348521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2349768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2350f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2351521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2352521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2353bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 23551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 23566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2357545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2358fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 23593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 23606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 23643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 23656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 236887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2369fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2370883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 23716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 237407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 237507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 237687c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 237787c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 23786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 23796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 23816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 23832b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 23842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 23852b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 23862b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 23872b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 23883c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23893c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 23903c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 23913c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2393fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 239401eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 23997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2400803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2401ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2402ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2403fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 24043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2409fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 24103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 24156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2416bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 24174a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 24184a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 241907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 242007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 242107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 24224a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 24234a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 24244a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 24254a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 24261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 242887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 24296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24302b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2431085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2432fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2433fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2434085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2435085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 24362b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2437390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2438390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2439803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2440390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2441fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2442fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 24436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2444bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 24456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 24466217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2447390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2448fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2449fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 24506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 24547a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2455803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2456ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2457ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2458fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 24593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 24606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 24646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 246587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 24666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 24676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 246887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 24696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 24743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 24752b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 24766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 2477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2478fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 24796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 24826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 2483fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 24843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 24856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2488b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // Check whether we already have an equivalent format attribute. 2489b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor for (specific_attr_iterator<FormatAttr> 249087c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<FormatAttr>(), 249187c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<FormatAttr>(); 2492b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor i != e ; ++i) { 2493b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor FormatAttr *f = *i; 2494b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getType() == Format && 2495b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFormatIdx() == (int)Idx.getZExtValue() && 2496b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFirstArg() == (int)FirstArg.getZExtValue()) { 2497b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // If we don't have a valid location for this attribute, adopt the 2498b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // location. 2499b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getLocation().isInvalid()) 2500ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis f->setRange(Attr.getRange()); 2501b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor return; 2502b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2503b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2504b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 2505768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format, 2506cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 25072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 25086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 25111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 25126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 25131731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 25146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25151731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 25166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 25180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 251987c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 25200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 25210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 25220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 252387c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 25240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 25250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 2526fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 25306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25315e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall if (!RD->isCompleteDefinition()) { 2532bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 25330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 25340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 25360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 253717945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 253817945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 25390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 25400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 25410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2543bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 25440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 25450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 254690cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2547bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 254890cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 254990cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 25500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 25510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2552bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 25530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 25540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 25550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 25560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 25570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 25580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 25590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 25600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2561bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 25620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 2563bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 25640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 25650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 25660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 2567bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 25680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 25690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 2570bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 2571bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 2572bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 25736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 25756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 25786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 25791731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 25806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 25827a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2583797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 25866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 25876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 2588797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 25896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 259177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 259277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Don't duplicate annotations that are already set. 259377f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge for (specific_attr_iterator<AnnotateAttr> 259477f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge i = D->specific_attr_begin<AnnotateAttr>(), 259577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 259677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge if ((*i)->getAnnotation() == SE->getString()) 259777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return; 259877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 2599768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 2600f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 26016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 26026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 26046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2605545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 26063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 26076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2609bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2610bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 2611bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 2612bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 26136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2614545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2615768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 26164ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 26174ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 26184ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 26204ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 26214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2622768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 26230b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne // FIXME: Handle pack-expansions here. 26240b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne if (DiagnoseUnexpandedParameterPack(E)) 26250b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne return; 26260b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne 26274ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 26284ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2629768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 26306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2632bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2633768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis SourceLocation AttrLoc = AttrRange.getBegin(); 2634cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 263549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 2636282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith ExprResult ICE = 2637282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith VerifyIntegerConstantExpression(E, &Alignment, 2638282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith PDiag(diag::err_attribute_argument_not_int) << "aligned", 2639282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith /*AllowFold*/ false); 2640282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith if (ICE.isInvalid()) 264149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 2642396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 26434ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 26444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2645396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2646396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2647396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2648282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take())); 2649cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2650cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2651768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2652cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2653cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2654768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2655cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 26566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2657fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2658d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 2659bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2660fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2661bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 26641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2665fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2666fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2667fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2668fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 26691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2670fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 26711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2672fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2673fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 26750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2677fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2678210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 26795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 2680fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2682210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2683210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2684fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2685fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2686fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 268773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2688210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 269073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 269173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 269273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 269473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 269673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 269773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 269873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 269973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 270073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 270173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 270273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 270373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 270473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 270573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2706fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 2708fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 2710210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 2711bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2712210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 2713bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 2714fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2715fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2716210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 2717bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2719fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2720fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2721fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2722162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2724fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2725fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2726fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2728768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << "mode" << Attr.getRange(); 2729fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2730fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 273173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2732183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 273373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 273473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 27352ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 273673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 273773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 273873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 273973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 274073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 274173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 274273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 274373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 274473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2745390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2746390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2747390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2748390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2749f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2750f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2751fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2752fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2753fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 27543c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2755fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2756fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 27573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2758fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2759fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 276073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 276173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 276273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 276373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2764fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 27650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2766fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2768fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2769fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 277073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 277173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 277273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 277373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2774fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 27750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2776fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2778fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2779fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2780fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2782fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 27830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2784fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2786fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2787fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2788fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2790fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2791bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2792aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2793aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2794aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2795fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2796bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2797aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2798aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2799aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2800fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 280173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 280273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 280373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2804f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2805f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2806f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2807f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2808f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2809f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2810f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2811f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2812f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 281373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2814fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2815fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 281673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 281773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2818fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2819fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2820fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2821162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2822ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2823a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2824ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2825fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2826fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 28270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 28281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2829d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 28301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2831d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2832e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 283387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 2834d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2835883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2836d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2837d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2838bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2839768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 2840d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2841d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 28421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 28435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 28441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 28455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 28461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2847bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 284887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 28495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2850883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 28515bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 28525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2853bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2854768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 28555bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 28565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 28571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 28581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 28597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 28601731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 28617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 28621731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 28637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 286487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 28657255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2866883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 28677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 28687255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 28697255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2870768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 2871f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 28727255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 28737255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 28741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2875ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2877831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2879ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 288287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2883ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2884883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2888768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 2889ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2892ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2896ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2898ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 290287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2904883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2908768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 2909ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2910ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2911ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2912ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2913ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2915ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2916ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2918ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2919ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 292087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2921ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2922883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2923ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2924ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2925ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 292687c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 29272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2928723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 29292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 29302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 29312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 29322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 29332c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 29342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 29352c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 29362c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 29372c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 29382c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 29392c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 29402c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2941768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 2942ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2943ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2944ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2945ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2946ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2948ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2949ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29501731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2951ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 29521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2953ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 295487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2955ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2956883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2957ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2958ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2959ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2960768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 2961ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2962ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2963ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2964ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2965ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2967ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2968ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 29691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2970ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 29711731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2972ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 297387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2974ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2975883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2976ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2977ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2978ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2979768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 2980ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2981ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2982ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2983ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2984ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 298626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 29871731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 298826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 2989bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 299087c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2991c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 299226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2993883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 299426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 299526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2996bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29970130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2998cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2999c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 3000c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 3001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3002768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 300326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 300426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 30051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 300687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3007711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 300887c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 3009e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 3010711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 301187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 3012711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3013e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 301487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 301587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 301687c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3017711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3018711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3019711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 302087c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3021e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 3023e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3024e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 3025768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 3026e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3027f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 3028768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 302904633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 3030e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 3031768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 3032e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 303352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3034768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 303552fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 3036414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 303787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *Arg = Attr.getArg(0); 3038414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 30395cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 304087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3041414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 304287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3043414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3044414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3045414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 30465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3047414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 3048414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") 3049414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 3050414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else if (StrRef == "aapcs-vfp") 3051414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 3052414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else { 305387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 305487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3055414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3056414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3057414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 3058768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 3059414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3060e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 3061e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 3062e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 3063e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 3064e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 30651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 306656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 3067768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 3068f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 3069f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 3070711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 3071711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 3072711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3073711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3074831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if ((attr.getNumArgs() != 0 && 3075831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 3076831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek attr.getParameterName()) { 3077711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3078711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 3079711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3080ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 308155d3aaf9a537888734762170823daf750ea9036dEli Friedman 3082414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 3083414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 3084711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 3085711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 3086711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 3087711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 3088711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 3089711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 3090414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 3091414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 3092414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 30935cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3094414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3095414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 3096414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 3097414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 3098414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3099414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 31005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3101414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 3102414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 3103414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3104414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 3105414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 3106414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3107414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3108414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // FALLS THROUGH 3109414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 31107530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("unexpected attribute kind"); 3111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3113711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3114711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3115711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 31161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 311787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3118711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3119711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 312087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3121711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3122711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 312387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 312487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 312587c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3126ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3127ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 312855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3129768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3130711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3131711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3132711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3133711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 313487c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 313587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3136711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3137711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 313887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 313987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 314087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3141711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3142711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3143711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 314487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 314555d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3146ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3147711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 314887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 314955d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 315087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3151711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 315255d3aaf9a537888734762170823daf750ea9036dEli Friedman } 315355d3aaf9a537888734762170823daf750ea9036dEli Friedman 3154bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 315587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 315655d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3158711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 315955d3aaf9a537888734762170823daf750ea9036dEli Friedman } 316055d3aaf9a537888734762170823daf750ea9036dEli Friedman 3161711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3162bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 316387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3164bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 316587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3166711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 316755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 316855d3aaf9a537888734762170823daf750ea9036dEli Friedman 3169711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3170ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3171ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 31721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 31737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 31747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 31757b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3176bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3177bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 31787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 318187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 31827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3183883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 31847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 31887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 31897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 31907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 31917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 31927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 31937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 31947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 31987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 31997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 32007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 32017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 32027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 32037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 32047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 32057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 32067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 32077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 32087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 3209768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 32107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 32117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 32127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 32137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 32147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 32157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 32167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 32170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3218b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3219b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3220b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 32226c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 32236c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isObjCObjectPointerType() || 32246c73a2975ba9112787380abd878876336957b3f6Douglas Gregor S.Context.isObjCNSObjectType(type); 3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 32276c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 32286c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isPointerType() || 32296c73a2975ba9112787380abd878876336957b3f6Douglas Gregor isValidSubjectOfNSAttribute(S, type); 3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3231c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 323387c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 323587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3236768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedParameter; 3237c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3238c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3239c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3240c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 324187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3242c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3243c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3244c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3245c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3246c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3248c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3249c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 325087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3251768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << cf; 3252c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3253c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3254c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3255c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 3256768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3257c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 3258768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3259c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3260c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 32621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 326387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 326487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3265768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedMethod; 3266c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3267c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3268c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3269768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3270c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3271c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 32721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 32731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3274b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3275c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3276bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 327787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3278c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 327987c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3280831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian returnType = PD->getType(); 32814e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 328287c44604325578b8de07d768391c1c9432404f5aChandler Carruth (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3283f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 328487c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3285c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 32865dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 328787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3288768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() 3289883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3290b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3291b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3292bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3293c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3294c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 329587c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 32967530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("invalid ownership attribute"); 3297c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3298c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 3299c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 3300c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3301c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3302c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3303c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3304c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 3305c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 3306c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3307c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3308c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3309c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3310c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3311c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 331287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3313768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3314bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 33155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 331787c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3318b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3319b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ownership attribute"); 3320c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3321768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3322c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3323c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 332431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3326f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 332731c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 332831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 3329768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3330f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 333131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 3332b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 3333768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3334f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3335b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3336b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3339b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3340b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3341b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3342b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3343dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3344dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3345dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3346dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3347dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3348dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 334994d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian if (!method) { 33500e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3351f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 3352dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3353dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3354dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3355dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3356dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 3357f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian 3358f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian if (!resultType->isReferenceType() && 3359f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3360dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3361dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3362dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3363dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3364dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3365dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3366dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3367dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3368dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3369768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3370dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3371dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 33728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer. 33738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 33748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!isa<FunctionDecl>(D)) { 33758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3376f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << A.getRange() << A.getName() << ExpectedFunction; 33778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 33818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Check whether there's a conflicting attribute already present. 33838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Attr *Existing; 33848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFUnknownTransferAttr>(); 33868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 33878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFAuditedTransferAttr>(); 33888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (Existing) { 33908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 33918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getName() 33928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 33938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << Existing->getRange(); 33948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // All clear; add the attribute. 33988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 34008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 34018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 34028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 34038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 34048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 34058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 34068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3407fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 3408fe98da0fa352462c02db037360788748f95466f7John McCall const AttributeList &Attr) { 3409fe98da0fa352462c02db037360788748f95466f7John McCall RecordDecl *RD = dyn_cast<RecordDecl>(D); 3410fe98da0fa352462c02db037360788748f95466f7John McCall if (!RD || RD->isUnion()) { 3411fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3412f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedStruct; 3413fe98da0fa352462c02db037360788748f95466f7John McCall } 3414fe98da0fa352462c02db037360788748f95466f7John McCall 3415fe98da0fa352462c02db037360788748f95466f7John McCall IdentifierInfo *ParmName = Attr.getParameterName(); 3416fe98da0fa352462c02db037360788748f95466f7John McCall 3417fe98da0fa352462c02db037360788748f95466f7John McCall // In Objective-C, verify that the type names an Objective-C type. 3418fe98da0fa352462c02db037360788748f95466f7John McCall // We don't want to check this outside of ObjC because people sometimes 3419fe98da0fa352462c02db037360788748f95466f7John McCall // do crazy C declarations of Objective-C types. 34204e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (ParmName && S.getLangOpts().ObjC1) { 3421fe98da0fa352462c02db037360788748f95466f7John McCall // Check for an existing type with this name. 3422fe98da0fa352462c02db037360788748f95466f7John McCall LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 3423fe98da0fa352462c02db037360788748f95466f7John McCall Sema::LookupOrdinaryName); 3424fe98da0fa352462c02db037360788748f95466f7John McCall if (S.LookupName(R, Sc)) { 3425fe98da0fa352462c02db037360788748f95466f7John McCall NamedDecl *Target = R.getFoundDecl(); 3426fe98da0fa352462c02db037360788748f95466f7John McCall if (Target && !isa<ObjCInterfaceDecl>(Target)) { 3427fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 3428fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(Target->getLocStart(), diag::note_declared_at); 3429fe98da0fa352462c02db037360788748f95466f7John McCall } 3430fe98da0fa352462c02db037360788748f95466f7John McCall } 3431fe98da0fa352462c02db037360788748f95466f7John McCall } 3432fe98da0fa352462c02db037360788748f95466f7John McCall 3433fe98da0fa352462c02db037360788748f95466f7John McCall D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 3434fe98da0fa352462c02db037360788748f95466f7John McCall ParmName)); 3435fe98da0fa352462c02db037360788748f95466f7John McCall} 3436fe98da0fa352462c02db037360788748f95466f7John McCall 34371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 34381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 343987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3440f85e193739c953358c865005855253af4f68a497John McCall 344187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3442f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3443f85e193739c953358c865005855253af4f68a497John McCall} 3444f85e193739c953358c865005855253af4f68a497John McCall 34451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 34461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 344787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 344887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3449f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3450f85e193739c953358c865005855253af4f68a497John McCall return; 3451f85e193739c953358c865005855253af4f68a497John McCall } 3452f85e193739c953358c865005855253af4f68a497John McCall 345387c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 3454f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 3455f85e193739c953358c865005855253af4f68a497John McCall 3456f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 3457f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 345887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3459f85e193739c953358c865005855253af4f68a497John McCall << type; 3460f85e193739c953358c865005855253af4f68a497John McCall return; 3461f85e193739c953358c865005855253af4f68a497John McCall } 3462f85e193739c953358c865005855253af4f68a497John McCall 3463f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3464f85e193739c953358c865005855253af4f68a497John McCall 3465f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 3466f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 3467f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3468f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 3469f85e193739c953358c865005855253af4f68a497John McCall 3470f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 3471f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 3472f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 3473f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 3474f85e193739c953358c865005855253af4f68a497John McCall break; 3475f85e193739c953358c865005855253af4f68a497John McCall 3476f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 3477f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 3478f85e193739c953358c865005855253af4f68a497John McCall break; 3479f85e193739c953358c865005855253af4f68a497John McCall 3480f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 3481f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 348287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3483f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 3484f85e193739c953358c865005855253af4f68a497John McCall break; 3485f85e193739c953358c865005855253af4f68a497John McCall } 3486f85e193739c953358c865005855253af4f68a497John McCall 348787c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 3488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3489f85e193739c953358c865005855253af4f68a497John McCall} 3490f85e193739c953358c865005855253af4f68a497John McCall 3491f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 34929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman switch (Attr.getKind()) { 34939428772f16e379bcad35254251f96e3d1077c730Aaron Ballman default: 34949428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return false; 34959428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllimport: 34969428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllexport: 34979428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_uuid: 34989428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_deprecated: 34999428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noreturn: 35009428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_nothrow: 35019428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_naked: 35029428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noinline: 35039428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return true; 35049428772f16e379bcad35254251f96e3d1077c730Aaron Ballman } 350511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 350611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 350711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 350811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 350911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 351011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 35111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 351262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 351311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 35141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 351511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 35161731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 351711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 351811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 35195cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3520d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3521d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 3522d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3523d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3524d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 35255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3526d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3527d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3528d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 3529f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 3530d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 3531d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 3532d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3533d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3534d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3535d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 3536d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3537d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3538d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3539d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3540f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3541d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 35425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 3543f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 3544f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 3545f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 3546f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 3547d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 3548d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 3549d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3550d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3551d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3552d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 3553d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3554d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3555d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3556d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 3557d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 355811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 3559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 356011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 3561d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 356211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3563f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 3564f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 3565b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 35660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 35670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 35680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 35691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 35701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 357160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 35721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 35731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 35741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 357560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 357660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 357760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 357860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 3579e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 35801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 35811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3582803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 3583e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_ibaction: handleIBAction(S, D, Attr); break; 3584e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutlet: handleIBOutlet(S, D, Attr); break; 3585e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutletcollection: 35861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 3587803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 3588207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 3589ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 35906e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 35914211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 35924211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 3593bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 3594bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 3595803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 359660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 359760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 359860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 359960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 360060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 360160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3604bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 36051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 3606b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 36081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3610bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 36111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 36131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 36141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 36161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 36173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 36193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 36211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 36221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 36247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 36267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 36271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 36281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 36291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 36311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3632dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 3633dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 3634dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 36351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 36361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 36371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 36381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 36391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 36401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3641b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3642b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis case AttributeList::AT_objc_ownership: 36431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 3644f85e193739c953358c865005855253af4f68a497John McCall case AttributeList::AT_objc_precise_lifetime: 36451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3646f85e193739c953358c865005855253af4f68a497John McCall 3647dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall case AttributeList::AT_objc_returns_inner_pointer: 3648dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3649dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3650fe98da0fa352462c02db037360788748f95466f7John McCall case AttributeList::AT_ns_bridged: 3651fe98da0fa352462c02db037360788748f95466f7John McCall handleNSBridgedAttr(S, scope, D, Attr); break; 3652fe98da0fa352462c02db037360788748f95466f7John McCall 36538dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_audited_transfer: 36548dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_unknown_transfer: 36558dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall handleCFTransferAttr(S, D, Attr); break; 36568dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 3658c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 36591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3660c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 36611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 3662c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3663c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 366431c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 366531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3666b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3667b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 36681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 3669b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3670e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_reqd_work_group_size: 36711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleReqdWorkGroupSize(S, D, Attr); break; 36726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 3673521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 36741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 3675521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 36761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 3677e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_ms_struct: handleMsStructAttr (S, D, Attr); break; 36781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 36791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3680e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_objc_arc_weak_reference_unavailable: 3681742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian handleArcWeakrefUnavailableAttr (S, D, Attr); 3682742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 3683b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard case AttributeList::AT_objc_root_class: 3684b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard handleObjCRootClassAttr(S, D, Attr); 3685b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard break; 368671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek case AttributeList::AT_objc_requires_property_definitions: 368771207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek handleObjCRequiresPropertyDefsAttr (S, D, Attr); 3688e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian break; 36891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 3690f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola case AttributeList::AT_returns_twice: 3691f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola handleReturnsTwiceAttr(S, D, Attr); 3692f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola break; 36931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 36941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 36951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3696026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 36971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 36981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 36991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3700803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 37011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 3702803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 37030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 37041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 37050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 3706d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 37071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 3708d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 3709e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_NSObject: handleObjCNSObject (S, D, Attr); break; 37101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 37111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 37121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 37131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 37141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 37151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 37161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 37171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3718bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 371905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 372005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 37217255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 37221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 37237255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 372404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 372504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 372604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 3727f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 372852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3729414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: 37301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 373104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 3732f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 37331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 3734f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 373511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 37361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 373711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 3738fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3739fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 3740fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_guarded_var: 3741fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 3742fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3743fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_pt_guarded_var: 3744fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3745fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3746fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_scoped_lockable: 3747fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr, /*scoped = */true); 3748fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 374971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany case AttributeList::AT_no_address_safety_analysis: 375071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany handleNoAddressSafetyAttr(S, D, Attr); 375171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany break; 3752fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_no_thread_safety_analysis: 3753fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 3754fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3755fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_lockable: 3756fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 3757fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3758db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_guarded_by: 3759db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 3760db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3761db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_pt_guarded_by: 3762db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3763db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3764db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_lock_function: 3765db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3766db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3767db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_locks_required: 3768db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3769db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3770db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_trylock_function: 3771db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3772db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3773db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_lock_returned: 3774db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 3775db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3776db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_locks_excluded: 3777db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 3778db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3779db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_lock_function: 3780db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr); 3781db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3782db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_locks_required: 3783db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr); 3784db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3785db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_trylock_function: 3786db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr); 3787db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3788db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_unlock_function: 3789db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 3790db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3791db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_before: 3792db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3793db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3794db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_after: 3795db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3796db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3797fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3798803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 379982d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 380082d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 380182d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 38027d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 38037d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 3804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 3805803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 380860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 380960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 381060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 381160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 38121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 38131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 381460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 381560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 381660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 381760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 381860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 381960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 382060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 382160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 382260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 38231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 382460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 382560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 38261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 382760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 382860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 3829803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3830803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 3831f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 383260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 383360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 383411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 38351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 383611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 383711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 383811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 383911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 384011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 384160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 384211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3843dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 384411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 3845803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3846803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3847803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 38485f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access 38495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier. 38505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 38515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen const AttributeList *AttrList) { 38525f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen for (const AttributeList* l = AttrList; l; l = l->getNext()) { 38535f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (l->getKind() == AttributeList::AT_annotate) { 38545f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen handleAnnotateAttr(*this, ASDecl, *l); 38555f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } else { 38565f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 38575f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return true; 38585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 38595f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 38605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 38615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return false; 38625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen} 38635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 3864e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it 3865e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about. 3866e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 3867e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for ( ; A; A = A->getNext()) { 3868e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall // Only warn if the attribute is an unignored, non-type attribute. 3869e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->isUsedAsTypeAttr()) continue; 3870e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::IgnoredAttribute) continue; 3871e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3872e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::UnknownAttribute) { 3873e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 3874e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3875e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } else { 3876e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 3877e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3878e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3879e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3880e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3881e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3882e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being 3883e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes 3884e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it. 3885e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 3886e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 3887e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getAttributes()); 3888e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 3889e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 3890e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3891e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 3894900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3895900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 38967b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3897e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 3898e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3899900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 3900900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 3901900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 3902900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 3903900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 3904900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3905900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 3906900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 3907900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 3908900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 3909900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 3910900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 3911900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 3912900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3913900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 3914c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 3915900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3916900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 3917900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 3918900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 3919900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3920900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 3921900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3922900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 3923900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3924900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 3925900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 3926900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 39274278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie NewFD->setParams(Params); 3928b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3929e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3930e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3931ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 3932a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 393316573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 393416573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 3935b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 3936b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 3937c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 3938b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3939e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3940e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 3941e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3942e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 3943e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3944e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 39457b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3946c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 3947c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 3948c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3949c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 3950900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3952cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 3953cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3954c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 3955c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3956c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 3957c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 3958c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 3959c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 3960c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 3961c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 3962cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3963e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3964e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3965e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 39660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 39670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 39680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 396960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 397060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 3971d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 3972d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 397331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 397431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 397531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 397631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 397731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 397831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 397931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 398031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 398131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 398231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 398331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 398431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 3985d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 3986e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3987e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3988e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3989e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 39900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 39917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 399260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3993bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 39940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 39950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 39960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 39970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 39980744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 39990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 400060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 4001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 40020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 40030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 400460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 40050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 400654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4007f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 4008f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 4009f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 4010f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 4011f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 4012a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian // Function declarations in sys headers will be marked unavailable. 4013a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 4014a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian !isa<FunctionDecl>(decl)) 4015f85e193739c953358c865005855253af4f68a497John McCall return false; 4016f85e193739c953358c865005855253af4f68a497John McCall 4017f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 4018f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 4019f85e193739c953358c865005855253af4f68a497John McCall} 4020f85e193739c953358c865005855253af4f68a497John McCall 4021f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 4022f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 4023f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 4024f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 4025f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 4026f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 4027f85e193739c953358c865005855253af4f68a497John McCall return; 4028f85e193739c953358c865005855253af4f68a497John McCall } 40294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount) 4030175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 4031175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // FIXME. we may want to supress diagnostics for all 4032175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // kind of forbidden type messages on unavailable functions. 4033175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (FD->hasAttr<UnavailableAttr>() && 4034175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.getForbiddenTypeDiagnostic() == 4035175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag::err_arc_array_param_no_ownership) { 4036175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.Triggered = true; 4037175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian return; 4038175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4039175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4040f85e193739c953358c865005855253af4f68a497John McCall 4041f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 4042f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 4043f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 4044f85e193739c953358c865005855253af4f68a497John McCall} 4045f85e193739c953358c865005855253af4f68a497John McCall 4046eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the 4047eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type. 4048eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 4049eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize <= StackCapacity); 4050eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4051eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Grow the stack if necessary. 4052eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackSize == StackCapacity) { 4053eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall unsigned newCapacity = 2 * StackCapacity + 2; 4054eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 4055eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall const char *oldBuffer = (const char*) Stack; 4056eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4057eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackCapacity) 4058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4060eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall delete[] oldBuffer; 4061eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 4062eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall StackCapacity = newCapacity; 4063eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall } 4064eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 4065eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize < StackCapacity); 4066eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall new (&Stack[StackSize++]) DelayedDiagnostic(diag); 406754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 406854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4069eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 4070eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Decl *decl) { 4071eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics &DD = S.DelayedDiagnostics; 407254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4073eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Check the invariants. 4074eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.StackSize >= state.SavedStackSize); 4075eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(state.SavedStackSize >= DD.ActiveStackBase); 4076eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.ParsingDepth > 0); 407754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4078eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Drop the parsing depth. 4079eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.ParsingDepth--; 408054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4081eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // If there are no active diagnostics, we're done. 4082eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DD.StackSize == DD.ActiveStackBase) 4083eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return; 408458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 40852f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 40862f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 4087e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (decl) { 4088eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // We emit all the active diagnostics, not just those starting 4089eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // from the saved state. The idea is this: we get one push for a 40902f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 40912f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 40922f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 40932f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 40942f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 4095eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 4096eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostic &diag = DD.Stack[i]; 4097eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 40982f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 40992f514480c448708ec382a684cf5e035d3a827ec8John McCall 4100eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 41012f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 4102e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall // Don't bother giving deprecation diagnostics if the decl is invalid. 4103e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (!decl->isInvalidDecl()) 4104e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall S.HandleDelayedDeprecationCheck(diag, decl); 41052f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 41062f514480c448708ec382a684cf5e035d3a827ec8John McCall 41072f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 4108eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedAccessCheck(diag, decl); 41092f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 4110f85e193739c953358c865005855253af4f68a497John McCall 4111f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 4112f85e193739c953358c865005855253af4f68a497John McCall handleDelayedForbiddenType(S, diag, decl); 4113f85e193739c953358c865005855253af4f68a497John McCall break; 411454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 411554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 411654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 411754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 411858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 4119eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 412029233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor DD.Stack[i].Destroy(); 412158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 4122eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.StackSize = state.SavedStackSize; 41232f514480c448708ec382a684cf5e035d3a827ec8John McCall} 41242f514480c448708ec382a684cf5e035d3a827ec8John McCall 41252f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 41262f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 41270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 41282f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 4129c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // A category implicitly has the availability of the interface. 4130c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 4131c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis return CatD->getClassInterface()->isDeprecated(); 41322f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 41332f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 41342f514480c448708ec382a684cf5e035d3a827ec8John McCall} 41352f514480c448708ec382a684cf5e035d3a827ec8John McCall 41369c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 41372f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 41382f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 41392f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 41402f514480c448708ec382a684cf5e035d3a827ec8John McCall 41412f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 4142ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 4143c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 4144ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 4145ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 4146b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian else if (DD.getUnknownObjCClass()) { 4147b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_fwdclass_message) 4148b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian << DD.getDeprecationDecl()->getDeclName(); 4149b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class); 4150b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian } 4151c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 4152c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 4153ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 415454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 415554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 41565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 41578e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 415889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 415954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 4160eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 4161b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 4162b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian UnknownObjCClass, 4163b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Message)); 416454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 416554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 416654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 416754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 41683a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 416954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 4170ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 4171c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 4172c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 41738e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 4174743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 41758e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 417689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian else { 41778e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 417889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 417989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian } 41808e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 418154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 4182