SemaDeclAttr.cpp revision adc6cbf5b502f1b58078455ab4fca66c7daac239
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins#include "clang/AST/CXXInheritance.h" 18384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 19b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h" 20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 21acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 22f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 23fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2419510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 259c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 26fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h" 27797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 299c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 32883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 33b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind { 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 44db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedVariableFunctionOrLabel, 45f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor ExpectedFieldOrGlobalVar, 46f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor ExpectedStruct 47883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall}; 48883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall 49e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 50e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 5387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D, 54a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 5687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 64bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 666217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 67755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 70183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 76d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 77a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 7887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) { 7987c44604325578b8de07d768391c1c9432404f5aChandler Carruth return getFunctionType(D, false) != NULL; 80a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 81a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 8587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) { 8687c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isFunction(D)|| isa<ObjCMethodDecl>(D); 87d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 9287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) { 9387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethod(D)) 94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 9687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 10087c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<BlockDecl>(D); 101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 102620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 103711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 104711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 10587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) { 106f85e193739c953358c865005855253af4f68a497John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 10787c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 10887c44604325578b8de07d768391c1c9432404f5aChandler Carruth isa<ObjCPropertyDecl>(D); 109711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 110711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 112d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 113620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 11487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) { 11587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 11672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 117620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 11887c44604325578b8de07d768391c1c9432404f5aChandler Carruth assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 119d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 120d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 1213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1223568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 123d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 124d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 12687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) { 12787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 12872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 130d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_size(); 1323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1333568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 13487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 13587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 13672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 138d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 139bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14087c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 1413568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1423568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 14387c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) { 14487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 1455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->getResultType(); 1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 14987c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) { 15087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) { 15172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 15387c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 154db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 155d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 15687c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->isVariadic(); 1573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 16087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) { 16187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 16207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 16307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 167183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 168b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 171506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 172506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 174bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 175506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 182085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 185085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1876217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 189085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 192465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 194085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 198b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May 199b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 2001731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 2011731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth unsigned int Num) { 2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (Attr.getNumArgs() != Num) { 2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return false; 2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth } 2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return true; 2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth} 2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 210db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 211b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May 212b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int Num) { 215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (Attr.getNumArgs() < Num) { 216db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 217db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return false; 218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return true; 221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// 224fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var 225fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable 226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 22739997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) { 228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (isa<FieldDecl>(D)) 229fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 23039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 232fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 236b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool. 237b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) { 238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = Exp->getType(); 239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return QT->isBooleanType() || QT->isIntegerType(); 240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 242aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 243aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// Check to see if the type is a smart pointer of some kind. We assume 244aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins// it's a smart pointer if it defines both operator-> and operator*. 24560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchinsstatic bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) { 24660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins DeclContextLookupConstResult Res1 = RT->getDecl()->lookup( 24760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins S.Context.DeclarationNames.getCXXOperatorName(OO_Star)); 24860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (Res1.first == Res1.second) 24960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return false; 25060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 25160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins DeclContextLookupConstResult Res2 = RT->getDecl()->lookup( 25260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow)); 25360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (Res2.first == Res2.second) 25460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return false; 25560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 25660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 257aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins} 258aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type. 260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message. 261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise 262ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, 263ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 26439997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 265fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski QualType QT = vd->getType(); 26639997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (QT->isAnyPointerType()) 267fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 268aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 26960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (const RecordType *RT = QT->getAs<RecordType>()) { 27060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // If it's an incomplete type, it could be a smart pointer; skip it. 27160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // (We don't want to force template instantiation if we can avoid it, 27260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // since that would alter the order in which templates are instantiated.) 27360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (RT->isIncompleteType()) 27460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 27560f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 27660f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (threadSafetyCheckIsSmartPointer(S, RT)) 27760f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return true; 27860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins } 279aed9ea398a3fd8d488120728e2df4ac81c3b0c4bDeLesley Hutchins 280ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) 281fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName()->getName() << QT; 282fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } else { 283fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 284fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName(); 285fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 286fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 287fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 288fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 289b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points 290b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit. 2917d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) { 2927d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const RecordType *RT = QT->getAs<RecordType>()) 293b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return RT; 2947d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2957d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer // Now check if we point to record type. 2967d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const PointerType *PT = QT->getAs<PointerType>()) 2977d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return PT->getPointeeType()->getAs<RecordType>(); 2987d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2997d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return 0; 300b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 301b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 302bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 303fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, 304fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose CXXBasePath &Path, void *Unused) { 305bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins const RecordType *RT = Specifier->getType()->getAs<RecordType>(); 306bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (RT->getDecl()->getAttr<LockableAttr>()) 307bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return true; 308bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return false; 309bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins} 310bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 311bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 3123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType 313ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// resolves to a lockable object. 31483cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchinsstatic void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 31583cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins QualType Ty) { 31683cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins const RecordType *RT = getRecordType(Ty); 31783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins 31883cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins // Warn if could not get record type for this argument. 319d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT) { 320ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class) 32183cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 32283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 3233ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 32460f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 325634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins // Don't check for lockable if the class hasn't been defined yet. 326634b2930f5a8fc4b153437657ce786ca3fba5b1eDeLesley Hutchins if (RT->isIncompleteType()) 32783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 32860f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 32960f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // Allow smart pointers to be used as lockable objects. 33060f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins // FIXME -- Check the type that the smart pointer points to. 33160f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins if (threadSafetyCheckIsSmartPointer(S, RT)) 33260f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins return; 33360f2024b7df091fb0d8b7e37334bc83ac66a5c39DeLesley Hutchins 334bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins // Check if the type is lockable. 335bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins RecordDecl *RD = RT->getDecl(); 336bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (RD->getAttr<LockableAttr>()) 33783cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins return; 338bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 339bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins // Else check if any base classes are lockable. 340bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { 341bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins CXXBasePaths BPaths(false, false); 342bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths)) 343bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins return; 3443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 345bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins 346bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) 347bbba25fa8e388e82e04f66784c2fc9f89b901abeDeLesley Hutchins << Attr.getName() << Ty.getAsString(); 3483ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski} 3493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 350b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 351ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins/// from Sidx, resolve to a lockable object. 3523ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with. 3533ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function 3543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list. 355ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchinsstatic void checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 3563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const AttributeList &Attr, 3573ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVectorImpl<Expr*> &Args, 358b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski int Sidx = 0, 359b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool ParamIdxOk = false) { 3603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 361b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski Expr *ArgExp = Attr.getArg(Idx); 3623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 363ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski if (ArgExp->isTypeDependent()) { 364ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // FIXME -- need to check this again on template instantiation 365ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski Args.push_back(ArgExp); 366ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski continue; 367ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski } 368b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 36979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) { 37079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // Ignore empty strings without warnings 37179747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (StrLit->getLength() == 0) 37279747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins continue; 37379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 374ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // We allow constant strings to be used as a placeholder for expressions 375ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // that are not valid C++ syntax, but warn that they are ignored. 376ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) << 377ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Attr.getName(); 378ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 379ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins } 380ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins 3813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 382b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 38379747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // A pointer to member expression of the form &MyClass::mu is treated 38479747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins // specially -- we need to look at the type of the member. 38579747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp)) 38679747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (UOp->getOpcode() == UO_AddrOf) 38779747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr())) 38879747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins if (DRE->getDecl()->isCXXInstanceMember()) 38979747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins ArgTy = DRE->getDecl()->getType(); 39079747e00e9f6b13b56e91462982d2456d0d9128fDeLesley Hutchins 3913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 3923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 393b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 3953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 397b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 398b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 399b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 400b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 4023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 4033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 404b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 405b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 406ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins continue; 407b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 4083ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 409b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 410b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 411b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 41283cad4544f8a89fb6a611f330d71d027c238375eDeLesley Hutchins checkForLockableRecord(S, D, Attr, ArgTy); 413b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 415b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 416b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 417b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 418e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 419e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 420e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 421e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 4223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 427fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool pointer = false) { 428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 429fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 436b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 439fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 440ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer) 444768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 445fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 446768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 450b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool pointer = false) { 451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 457db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 458db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 459b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 460db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 463ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) 464db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 465db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 466ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins SmallVector<Expr*, 1> Args; 467ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // check that all arguments are lockable objects 468ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 469ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins unsigned Size = Args.size(); 470ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size != 1) 471ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 472ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr *Arg = Args[0]; 473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 474db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer) 475768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 4763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, Arg)); 477db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 478768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 479db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 480db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 481db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 482fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 483fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool scoped = false) { 484fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 485fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 486fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 487fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 488fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4891748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski // FIXME: Lockable structs for C code. 490fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 491fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 492fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedClass; 493fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 494fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 495fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 496fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (scoped) 497768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 498fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 499768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 500fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 501fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 502fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 503fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 504fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 505fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 506fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 507fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 508fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 510fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 511fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 512fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 513fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 514fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 515768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 516fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 517fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 518fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 51971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryanystatic void handleNoAddressSafetyAttr(Sema &S, Decl *D, 520ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins const AttributeList &Attr) { 52171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany assert(!Attr.isInvalid()); 52271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 52371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!checkAttributeNumArgs(S, Attr, 0)) 52471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 52571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 52671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 52771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 52871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany << Attr.getName() << ExpectedFunctionOrMethod; 52971efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany return; 53071efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany } 53171efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 53271efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(), 53371efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany S.Context)); 53471efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany} 53571efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany 536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski bool before) { 538db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 539db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 541db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 542db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 543db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 544b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 545b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 546db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 548db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 549db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 550db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 551ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that this attribute only applies to lockable types. 552b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 553b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 554b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 555b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 556ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) 557b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 558b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 559b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 560b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 561b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5623ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 563ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins // Check that all arguments are lockable objects. 564ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 5653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 566ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 567ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 568ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 5693ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (before) 571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 5723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 5753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 577db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 578db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 579b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 580db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 581db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 582db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 583db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 584b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 585b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 587db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 588db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 589db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 591b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 593ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 5943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5953ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 597db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 598768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 5993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 602768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 6033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6043ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 609db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 610db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 612db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 613db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 614b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 615db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 616db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 617db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 618db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 620b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 621b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 623b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 624b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 625b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 2> Args; 627b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 628ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1); 6293ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6303ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6313ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 633768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 6343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, 63569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 6363ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 637db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 638768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 63969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski S.Context, 64069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 64169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski StartArg, Size)); 642db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 645b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 646db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 648b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 649db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 651b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 652db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 657b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6583ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 659ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 661ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 662ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 663ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 6673ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 670768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 6713ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 6723ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 676b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 681b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 685db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 686db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 687b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 689ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true); 6903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 693768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 6943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 698b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 701b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 702db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 7033ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 704db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 705b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 706db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 707db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 708db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 709db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 710db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 7113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 712b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 713b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 7143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 715f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins SmallVector<Expr*, 1> Args; 716f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 717f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins unsigned Size = Args.size(); 718f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins if (Size == 0) 719f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins return; 7203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 721f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, 722f26efd79d1bd139641d0bb40842f908c67f041c2DeLesley Hutchins Args[0])); 723db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 724db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 725db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 726b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 727db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 728db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 729b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 730db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 731db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 732b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 733db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 734db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 735db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 736db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 737db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 738b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 7393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 740ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins checkAttrArgsAreLockableObjs(S, D, Attr, Args); 7413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 742ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins if (Size == 0) 743ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins return; 744ae519c42a1e0a023be6c07ba1dc10f28e29d6bc3DeLesley Hutchins Expr **StartArg = &Args[0]; 7453ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 746768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 7473ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 748db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 749db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 750db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 7511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 7521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 75387c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 754545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 755803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 756545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 758bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 7609cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7619cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 7629cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7639cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 7649cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 765f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 766e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 767f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 768f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 7694ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 770e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara ExprResult Size = S.ActOnIdExpression(scope, SS, TemplateKWLoc, id, 771e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara false, false); 7724ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 7734ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 7744ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 7754ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 7769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 7779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 7781731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 7799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 7801731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 7817a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 7859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 7869ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 7879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 788ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 789a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 790bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 7929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 7936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 7976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 7981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 800bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 80187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 802768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 80387c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 8056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 8066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 808fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 80908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 811768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 8133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 8146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 81787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 818768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 819c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 820c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 821c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 822c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 8231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 82496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 8251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 82696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 827bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 82863e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 82987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 83063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 831768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 83263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 83363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 83463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 8354ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 83663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 83763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 8382f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 8392f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // The IBOutlet/IBOutletCollection attributes only apply to instance 8402f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // variables or properties of Objective-C classes. The outlet must also 8412f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // have an object reference type. 8422f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 8432f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 8440bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 8452f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << VD->getType() << 0; 8462f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 8472f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 8482f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 8492f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 8502f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 851f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 8522f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << PD->getType() << 1; 8532f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 8542f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 8552f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 8562f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else { 8572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 8582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 8592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 860f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 8612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return true; 8622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek} 8632f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 8641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 86563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 8661731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 86763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 8682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 8692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 87063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 87163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 8722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 87396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 87496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 8751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 8761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 877857e918a8a40deb128840308a318bf623d68295fTed Kremenek 878857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 879a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 880857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 881857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 882857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 883857e918a8a40deb128840308a318bf623d68295fTed Kremenek 8842f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 885857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 8862f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 887a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 888a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 889f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian II = &S.Context.Idents.get("NSObject"); 8903a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 891b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 89287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 893a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 894a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 895a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 896a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 897b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 898a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 899a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 900a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 901a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 902f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 903a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 904a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 905a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 906f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 907f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis QT, Attr.getParameterLoc())); 908857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 909857e918a8a40deb128840308a318bf623d68295fTed Kremenek 910d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 91168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 91268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 91368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 91468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 91568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 91668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 91768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 91868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 91968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 92068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 92168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 92268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 92368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 92468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 925587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopesstatic void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 926587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 927587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 928587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 929587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // In C++ the implicit 'this' function parameter also counts, and they are 930587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // counted from one. 931587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes bool HasImplicitThisParam = isInstanceMethod(D); 932587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 933587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 934587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes SmallVector<unsigned, 8> SizeArgs; 935587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 936587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes for (AttributeList::arg_iterator I = Attr.arg_begin(), 937587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes E = Attr.arg_end(); I!=E; ++I) { 938587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // The argument must be an integer constant expression. 939587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes Expr *Ex = *I; 940587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes llvm::APSInt ArgNum; 941587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (Ex->isTypeDependent() || Ex->isValueDependent() || 942587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 943587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 944587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 945587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 946587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 947587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 948587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes uint64_t x = ArgNum.getZExtValue(); 949587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 950587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (x < 1 || x > NumArgs) { 951587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 952587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << I.getArgNum() << Ex->getSourceRange(); 953587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 954587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 955587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 956587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes --x; 957587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (HasImplicitThisParam) { 958587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (x == 0) { 959587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), 960587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes diag::err_attribute_invalid_implicit_this_argument) 961587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 962587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 963587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 964587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes --x; 965587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 966587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 967587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // check if the function argument is of an integer type 968587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 969587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!T->isIntegerType()) { 970587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 971587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << Ex->getSourceRange(); 972587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 973587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 974587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 975587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // check if the argument is a duplicate 976587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes SmallVectorImpl<unsigned>::iterator Pos; 977587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes Pos = std::find(SizeArgs.begin(), SizeArgs.end(), x); 978587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (Pos != SizeArgs.end()) { 979587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::err_attribute_argument_duplicate) 980587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << I.getArgNum() << Ex->getSourceRange(); 981587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes return; 982587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 983587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 984587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes SizeArgs.push_back(x); 985587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 986587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 987587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes // check if the function returns a pointer 988587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes if (!getFunctionType(D)->getResultType()->isAnyPointerType()) { 989587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 990587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange(); 991587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes } 992587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 993587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes unsigned size = SizeArgs.size(); 994587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes unsigned* start = &SizeArgs[0]; 995587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes llvm::array_pod_sort(start, start + size); 996587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context, start, 997587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes size)); 998587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes} 999587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes 10001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1001bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 1002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 100387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 1004fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1005883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1006eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1007eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1008bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 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; 1013eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 1014eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 10155f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 1016bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1017eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 1018eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 1019bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1020bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1021eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 10227a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 1023eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 1024ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 1025ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 1026fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1027fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 1028eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1029eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1030bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1031eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1032bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1033eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 1034fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 103530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 1036eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 1037eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1038bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1039465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 104007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 104107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 104207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 104307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 104407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 104507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 104607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 104707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 104807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 1049eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 1050eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 105187c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 1052d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 105368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 1054dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1055eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 1056c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 1057fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 10587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 1059eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1060bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1061eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 1062eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 1063bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1064bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 1065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 10667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 106787c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 106887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 1069d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 1070dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 1071d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 107246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 1073bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1074ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 107560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 107660acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 107760acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 107860acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 107960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 10807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 108160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 1082eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 10837fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 10847fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 10857fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 1086dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1087768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 1089eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 1090eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 10911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 1093dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 1094dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 1095dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 1096dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 1097dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 10982a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 10992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 1100dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1101dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 1102dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 1103dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 1104dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1105dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1106dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 1107cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 11082a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 11092a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 1110cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 1111dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 1112dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1113dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1114dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 11152a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 11162a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 1117cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 1118dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 1119dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1120dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1121dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 11222a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 11232a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 1124cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 1125dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1126dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 1127dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 1128dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1129dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 11302a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 11312a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 11322a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 11332a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 1134dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1135dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 113687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 1137883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 1138883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 1139dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1140dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1141dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 114207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 114307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 114487c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 114587c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 1146dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 11475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 1148dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1149dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 1150dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 1151dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 1152dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 11535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 1154dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 11552a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 11562a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 1157dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 11587a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 1159dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1160dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1161dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1162dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1163dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1164dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1165dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1166dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1167dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1168dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1169dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1170dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1171dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1172dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1173dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1174dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 117507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 117607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 117707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 117807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 117907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 118007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 118107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 118207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 118307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1184dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1185cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1186cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1187dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 118887c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1189dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1190dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1191dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1192cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1193dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1194dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1195dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1196dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1197dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1198dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1199cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1200dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1201dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 12027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1203dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1204dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1205dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1206dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1207dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1208dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1209dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1210dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1211dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1212dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1213dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1214dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1215dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1216dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1217cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 121887c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 121987c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1220cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1221cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1222cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1223cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1224cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1225cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1226cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1227dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1228dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1229dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1230dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1231dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1232dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1233dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1234dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1235dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1236dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1237cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1238cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1239cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1240cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1241dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1242cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 124387c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1244cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1245dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1246dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1247332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1248332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1249332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1250332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1251332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1252332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1253332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1254332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1255332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1256332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1257332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1258332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1259332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1260332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1261332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1262332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1263332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 126411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 126511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 12661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 126711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 126811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 126911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 127011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 127111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 127211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 127387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1274332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1275883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1276332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1277332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1278332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 127987c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1280332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 128111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 128211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 128311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 128411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 128511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 128611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 128711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 128811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 128911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 129011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 129187c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 12927a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 12937a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1294332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 12957a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 129611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 129711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 129811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 129911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 130011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 130111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 130211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 130311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 130411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 130511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 130611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 130711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 130811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 130911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 131011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 131111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 131211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 131311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 131411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 131511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1316332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1317332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 131811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 131911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 132011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 132111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 132211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 132311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 132411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 132511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 13267a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 132711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 132811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 132911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 13305cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 133111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 133211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 133311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 133411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 133511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 133611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 1337768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1338f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 133911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 134011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1341768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 134211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 134311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 13441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 13456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1346545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 13473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13517a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 13526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 13536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1354bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13555cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 13573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 13586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1361bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1362f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1363f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1364f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1365f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 13666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1367bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1368768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1369f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 13706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1372ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1373ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer // Check the attribute arguments. 1374ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!checkAttributeNumArgs(S, Attr, 0)) 1375ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1376ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1377ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!isa<FunctionDecl>(D)) { 1378ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1379ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << ExpectedFunction; 1380ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1381ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1382ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1383ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (D->hasAttr<HotAttr>()) { 1384ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1385ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << "hot"; 1386ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1387ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1388ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1389ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context)); 1390ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer} 1391ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1392ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramerstatic void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1393ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer // Check the attribute arguments. 1394ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!checkAttributeNumArgs(S, Attr, 0)) 1395ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1396ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1397ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (!isa<FunctionDecl>(D)) { 1398ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1399ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << ExpectedFunction; 1400ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1401ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1402ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1403ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer if (D->hasAttr<ColdAttr>()) { 1404ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 1405ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer << Attr.getName() << "cold"; 1406ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer return; 1407ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer } 1408ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 1409ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context)); 1410ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer} 1411ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer 14121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1413dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 14141731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1415dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1416dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 141787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1418dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1419883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1420dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1421dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1422dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 1423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1424dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1425dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 14261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 14271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1428dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1429831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 14303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1431af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1432af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 14335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 143487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 14355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1436883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 14375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 14385bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1439bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1440768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1441af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1442af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 14431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1444dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1445831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 144676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 144776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 144876168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 14491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 145087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 14511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 14522cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1453768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 14542cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 14552cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1456fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1457fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 14582cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 145976168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 146076168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 14611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 146234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 14631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 146434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 146534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 1466768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 146734c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 146834c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 14691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 147056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 147187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1472768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1473722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1474722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1475883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1476a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1477a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 14781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 147956aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 148087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1481768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1482722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1483722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1484883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1485a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1486a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 14871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 148887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1489711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1490711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1491711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 149287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1493711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1494883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1495711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1496711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1497711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1498768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1499711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1500711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1501711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1502831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1503711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1504711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1505711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1506711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1507711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1508711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1509b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1510b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 15111b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 15121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1513b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1514b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1515b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 1516b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 15171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 15181731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 1519b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 152087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 152187c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 15223ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 15233ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1524e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1525e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1526b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1527883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1528b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 152919c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 15306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1531b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1532768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 15336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 153535cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 15361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 153735cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 153835cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 153935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 1540f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 1541f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1542f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1543f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1544f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 154535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 154635cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 154735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 154835cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 154935cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 155035cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 155135cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 155235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 155335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 155435cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 155535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 155635cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 155735cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 155835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 155935cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 156087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 156135cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1562883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 156335cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 156435cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 156535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 156687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 156735cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 156835cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 156935cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 157035cc9627340b15232139b3c43fcde5973e7fad30John Thompson 157187c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 157201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 157301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 157401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 157501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 157601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 157701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 157801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 157901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 158001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 158101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 158201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 158301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1584f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1585f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 158601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 158701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 158801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 158901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 159001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 159101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 159201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1593768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 159435cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 159535cc9627340b15232139b3c43fcde5973e7fad30John Thompson 15961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 159787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1599883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1601bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1602bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1603bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1604bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 16051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 160673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1607831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 16083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 160973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 161073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1611bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 161287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 1613568eae48a4e19c0359cdcd2a33b8ec9812e4abbcDaniel Jasper !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) { 1614fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1615883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 161673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 161773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1618bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 162073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 162173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 1622f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D, 1623f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola const AttributeList &Attr) { 1624f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola // check the attribute arguments. 1625f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (Attr.hasParameterOrArguments()) { 1626f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1627f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1628f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1629f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1630f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (!isa<FunctionDecl>(D)) { 1631f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1632f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola << Attr.getName() << ExpectedFunction; 1633f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1634f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1635f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1636f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1637f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola} 1638f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 16391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1640b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1641831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1642b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1643b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1644b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1645bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 164687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1647186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1648b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1649b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1650b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 165187c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1652b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1653883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1654b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1655b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1656bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1657768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1658b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1659b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 16601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1662bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1663bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 16643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 16663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 16673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 16683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 16697a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 16703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1671ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1672ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1673fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 16743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 16753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 16763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 16773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 16783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 168087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1681fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1682883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 16833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 16843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 16853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1686768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1687f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 16883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 16893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 16901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1692bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1693bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 16943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1695bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 16963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 16973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 16983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 16997a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 17003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1701ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1702ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1703fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 17043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 17053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 17063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 17073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 17083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 171087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1711fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1712883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 17133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 17143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 17153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1716768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1717f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 17183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 17193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1720bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramertemplate <typename AttrTy> 1721bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramerstatic void handleAttrWithMessage(Sema &S, Decl *D, const AttributeList &Attr, 1722bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer const char *Name) { 1723951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1724951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1725bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1726c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1727c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1728bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer 1729bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer // Handle the case where the attribute has a text message. 17305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1731951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1732951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1733c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1734951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1735bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer << Name; 1736c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1737c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1738951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 17396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1741bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str)); 1742bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1743bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1744742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1745742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1746742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1747742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1748742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1749742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1750742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 1751742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1752742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1753768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis Attr.getRange(), S.Context)); 1754742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1755742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1756b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beardstatic void handleObjCRootClassAttr(Sema &S, Decl *D, 1757b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard const AttributeList &Attr) { 1758b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (!isa<ObjCInterfaceDecl>(D)) { 1759b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 1760b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1761b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1762b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1763b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard unsigned NumArgs = Attr.getNumArgs(); 1764b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard if (NumArgs > 0) { 1765b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1766b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard return; 1767b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard } 1768b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 1769b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context)); 1770b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard} 1771b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard 177271207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenekstatic void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 1773e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian const AttributeList &Attr) { 1774341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian if (!isa<ObjCInterfaceDecl>(D)) { 1775341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis); 1776341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian return; 1777341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian } 1778341b8be2b8069e09eb4d928bebf5d55a50515614Fariborz Jahanian 1779e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1780e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian if (NumArgs > 0) { 1781e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1782e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian return; 1783e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian } 1784e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 178571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr( 1786e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian Attr.getRange(), S.Context)); 1787e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian} 1788e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian 1789fad5de9d674521017460f8445e2f81e2a1086290Jordy Rosestatic bool checkAvailabilityAttr(Sema &S, SourceRange Range, 1790fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose IdentifierInfo *Platform, 1791fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Introduced, 1792fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Deprecated, 1793fad5de9d674521017460f8445e2f81e2a1086290Jordy Rose VersionTuple Obsoleted) { 17945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 17950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 17963b294360febd89e3383143af086efe2014571afaRafael Espindola if (PlatformName.empty()) 17970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 17980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1799c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 18000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 18013b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Introduced.empty() && !Deprecated.empty() && 18023b294360febd89e3383143af086efe2014571afaRafael Espindola !(Introduced <= Deprecated)) { 18033b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 18043b294360febd89e3383143af086efe2014571afaRafael Espindola << 1 << PlatformName << Deprecated.getAsString() 18053b294360febd89e3383143af086efe2014571afaRafael Espindola << 0 << Introduced.getAsString(); 18063b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 18070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 18080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 18093b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Introduced.empty() && !Obsoleted.empty() && 18103b294360febd89e3383143af086efe2014571afaRafael Espindola !(Introduced <= Obsoleted)) { 18113b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 18123b294360febd89e3383143af086efe2014571afaRafael Espindola << 2 << PlatformName << Obsoleted.getAsString() 18133b294360febd89e3383143af086efe2014571afaRafael Espindola << 0 << Introduced.getAsString(); 18143b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 18153b294360febd89e3383143af086efe2014571afaRafael Espindola } 18163b294360febd89e3383143af086efe2014571afaRafael Espindola 18173b294360febd89e3383143af086efe2014571afaRafael Espindola if (!Deprecated.empty() && !Obsoleted.empty() && 18183b294360febd89e3383143af086efe2014571afaRafael Espindola !(Deprecated <= Obsoleted)) { 18193b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(Range.getBegin(), diag::warn_availability_version_ordering) 18203b294360febd89e3383143af086efe2014571afaRafael Espindola << 2 << PlatformName << Obsoleted.getAsString() 18213b294360febd89e3383143af086efe2014571afaRafael Espindola << 1 << Deprecated.getAsString(); 18223b294360febd89e3383143af086efe2014571afaRafael Espindola return true; 18233b294360febd89e3383143af086efe2014571afaRafael Espindola } 18243b294360febd89e3383143af086efe2014571afaRafael Espindola 18253b294360febd89e3383143af086efe2014571afaRafael Espindola return false; 18263b294360febd89e3383143af086efe2014571afaRafael Espindola} 18273b294360febd89e3383143af086efe2014571afaRafael Espindola 1828599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaAvailabilityAttr *Sema::mergeAvailabilityAttr(Decl *D, SourceRange Range, 1829599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola IdentifierInfo *Platform, 1830599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Introduced, 1831599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Deprecated, 1832599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VersionTuple Obsoleted, 1833599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola bool IsUnavailable, 1834599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola StringRef Message) { 183598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedIntroduced = Introduced; 183698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedDeprecated = Deprecated; 183798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedObsoleted = Obsoleted; 18383b294360febd89e3383143af086efe2014571afaRafael Espindola bool FoundAny = false; 18393b294360febd89e3383143af086efe2014571afaRafael Espindola 184098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (D->hasAttrs()) { 184198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola AttrVec &Attrs = D->getAttrs(); 184298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola for (unsigned i = 0, e = Attrs.size(); i != e;) { 184398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola const AvailabilityAttr *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]); 184498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (!OldAA) { 184598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 184698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 184798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 184898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 184998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola IdentifierInfo *OldPlatform = OldAA->getPlatform(); 185098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (OldPlatform != Platform) { 185198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 185298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 185398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 185498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 185598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola FoundAny = true; 185698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldIntroduced = OldAA->getIntroduced(); 185798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldDeprecated = OldAA->getDeprecated(); 185898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple OldObsoleted = OldAA->getObsoleted(); 185998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola bool OldIsUnavailable = OldAA->getUnavailable(); 186098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola StringRef OldMessage = OldAA->getMessage(); 186198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 186298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if ((!OldIntroduced.empty() && !Introduced.empty() && 186398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldIntroduced != Introduced) || 186498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (!OldDeprecated.empty() && !Deprecated.empty() && 186598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldDeprecated != Deprecated) || 186698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (!OldObsoleted.empty() && !Obsoleted.empty() && 186798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola OldObsoleted != Obsoleted) || 186898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (OldIsUnavailable != IsUnavailable) || 186998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola (OldMessage != Message)) { 187098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(OldAA->getLocation(), diag::warn_mismatched_availability); 187198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 187298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Attrs.erase(Attrs.begin() + i); 187398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola --e; 187498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 187598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 187698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 187798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedIntroduced2 = MergedIntroduced; 187898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedDeprecated2 = MergedDeprecated; 187998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VersionTuple MergedObsoleted2 = MergedObsoleted; 188098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 188198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedIntroduced2.empty()) 188298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced2 = OldIntroduced; 188398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedDeprecated2.empty()) 188498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedDeprecated2 = OldDeprecated; 188598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (MergedObsoleted2.empty()) 188698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted2 = OldObsoleted; 188798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 188898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform, 188998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced2, MergedDeprecated2, 189098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted2)) { 189198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Attrs.erase(Attrs.begin() + i); 189298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola --e; 189398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola continue; 189498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 189598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 189698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedIntroduced = MergedIntroduced2; 189798ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedDeprecated = MergedDeprecated2; 189898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola MergedObsoleted = MergedObsoleted2; 189998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ++i; 190098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 19010a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 19020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 19033b294360febd89e3383143af086efe2014571afaRafael Espindola if (FoundAny && 19043b294360febd89e3383143af086efe2014571afaRafael Espindola MergedIntroduced == Introduced && 19053b294360febd89e3383143af086efe2014571afaRafael Espindola MergedDeprecated == Deprecated && 19063b294360febd89e3383143af086efe2014571afaRafael Espindola MergedObsoleted == Obsoleted) 1907599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 19083b294360febd89e3383143af086efe2014571afaRafael Espindola 190998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced, 19103b294360febd89e3383143af086efe2014571afaRafael Espindola MergedDeprecated, MergedObsoleted)) { 1911599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) AvailabilityAttr(Range, Context, Platform, 1912599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Introduced, Deprecated, 1913599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Obsoleted, IsUnavailable, Message); 19140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 1915599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 19163b294360febd89e3383143af086efe2014571afaRafael Espindola} 19170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 19183b294360febd89e3383143af086efe2014571afaRafael Espindolastatic void handleAvailabilityAttr(Sema &S, Decl *D, 19193b294360febd89e3383143af086efe2014571afaRafael Espindola const AttributeList &Attr) { 19203b294360febd89e3383143af086efe2014571afaRafael Espindola IdentifierInfo *Platform = Attr.getParameterName(); 19213b294360febd89e3383143af086efe2014571afaRafael Espindola SourceLocation PlatformLoc = Attr.getParameterLoc(); 19223b294360febd89e3383143af086efe2014571afaRafael Espindola 19233b294360febd89e3383143af086efe2014571afaRafael Espindola if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty()) 19243b294360febd89e3383143af086efe2014571afaRafael Espindola S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 19253b294360febd89e3383143af086efe2014571afaRafael Espindola << Platform; 19263b294360febd89e3383143af086efe2014571afaRafael Espindola 19273b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 19283b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 19293b294360febd89e3383143af086efe2014571afaRafael Espindola AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 19303b294360febd89e3383143af086efe2014571afaRafael Espindola bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 1931006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian StringRef Str; 1932006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian const StringLiteral *SE = 1933006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian dyn_cast_or_null<const StringLiteral>(Attr.getMessageExpr()); 1934006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian if (SE) 1935006e42f0c8b65b783d565ef10b938a9e82fc02e3Fariborz Jahanian Str = SE->getString(); 19363b294360febd89e3383143af086efe2014571afaRafael Espindola 1937599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(D, Attr.getRange(), 1938599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Platform, 1939599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Introduced.Version, 1940599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Deprecated.Version, 1941599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Obsoleted.Version, 1942599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola IsUnavailable, Str); 1943599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 1944599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 194598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola} 194698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola 1947599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaVisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range, 1948599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VisibilityAttr::VisibilityType Vis) { 1949dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola if (isa<TypedefNameDecl>(D)) { 1950dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility"; 1951599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 1952dd44f34301316b814277d6a8c146d86c7115330bRafael Espindola } 195398ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VisibilityAttr *ExistingAttr = D->getAttr<VisibilityAttr>(); 195498ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (ExistingAttr) { 195598ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola VisibilityAttr::VisibilityType ExistingVis = ExistingAttr->getVisibility(); 195698ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola if (ExistingVis == Vis) 1957599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 195898ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(ExistingAttr->getLocation(), diag::err_mismatched_visibility); 195998ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 196098ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola D->dropAttr<VisibilityAttr>(); 196198ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola } 1962599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) VisibilityAttr(Range, Context, Vis); 19630a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 19640a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 19651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 19671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 19686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1969bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19707a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 19716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 19726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1973bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19745cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1975fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 19763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 19776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1979bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 19805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 1981cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1982bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1983c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1984cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1985c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1986cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1987c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1988cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 19894188760f6bb20f91c6883dffd89204419f852deeJohn McCall else if (TypeStr == "protected") { 19904188760f6bb20f91c6883dffd89204419f852deeJohn McCall // Complain about attempts to use protected visibility on targets 19914188760f6bb20f91c6883dffd89204419f852deeJohn McCall // (like Darwin) that don't support it. 19924188760f6bb20f91c6883dffd89204419f852deeJohn McCall if (!S.Context.getTargetInfo().hasProtectedVisibility()) { 19934188760f6bb20f91c6883dffd89204419f852deeJohn McCall S.Diag(Attr.getLoc(), diag::warn_attribute_protected_visibility); 19944188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Default; 19954188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 19964188760f6bb20f91c6883dffd89204419f852deeJohn McCall type = VisibilityAttr::Protected; 19974188760f6bb20f91c6883dffd89204419f852deeJohn McCall } 19984188760f6bb20f91c6883dffd89204419f852deeJohn McCall } else { 199908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 20006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 20016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2002bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2003599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type); 2004599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2005599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 20066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 20091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 2010d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 2011d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 201287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 2013883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 2014d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2015d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2016d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 201787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 201887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 201987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2020d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 2021d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 202287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2023d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 202487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2025d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2026d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2027d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 20285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 2029d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 2030d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 2031d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 2032d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 2033d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 2034d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 2035d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 2036d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 2037d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 2038d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 2039d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 2040d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 2041d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 2042d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 2043d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 2044d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 204587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 2046d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 2047d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 2048d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 2049f85e193739c953358c865005855253af4f68a497John McCall if (family == ObjCMethodFamilyAttr::OMF_init && 2050f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 2051f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 2052f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 2053f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 2054f85e193739c953358c865005855253af4f68a497John McCall return; 2055f85e193739c953358c865005855253af4f68a497John McCall } 2056f85e193739c953358c865005855253af4f68a497John McCall 2057768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 2058f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 2059d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 2060d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 20611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 20621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 20631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 20640db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 2065bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 20660db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 20670db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 20680db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 20690db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 20700db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 2071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2072768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 20730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 20740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 20751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 2076fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 20772b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2078fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 2079fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 2080162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2081fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 2082fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 20836217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 2084fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 2085fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 2086fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 2087fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 20883427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 20893427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian QualType T = PD->getType(); 20903427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian if (!T->isPointerType() || 20913427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 20923427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian S.Diag(PD->getLocation(), diag::err_nsobject_attribute); 20933427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian return; 20943427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian } 20953427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian } 20963427682d365174f5d69d55e2c6deef49ace0668bFariborz Jahanian else { 2097f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // It is okay to include this attribute on properties, e.g.: 2098f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 2099f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject)); 2100f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // 2101f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // In this case it follows tradition and suppresses an error in the above 2102f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek // case. 21039b2eb7b1a1bdd1fe4acb200b448312ef407283dfFariborz Jahanian S.Diag(D->getLocation(), diag::warn_nsobject_attribute); 2104f6e88d7592a5b5ab19890a41ff71f5bf8ca2a9faTed Kremenek } 2105768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 2106fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 2107fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 2108bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 21091b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2110f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 21112b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2112f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 2113f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 2114f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 2115f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 2116f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 2117f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 2118f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 2119f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 2120768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 2121f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 2122f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 21231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2124bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2125fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 21263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 21279eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 21289eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2129bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 21313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 21329eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 21339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2134bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2135cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 213692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 21379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 21389eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 2139fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 21403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 21419eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 21429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 2143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2144768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 21459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 21469eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 21471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2148770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 2149770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 2150bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 2151770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2152bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21543323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned sentinel = 0; 2155770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 21567a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 2157770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 2158ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2159ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 2160fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 21613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 2162770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2163770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2164bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21653323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if (Idx.isSigned() && Idx.isNegative()) { 2166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 2167fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 2168770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2169770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 21703323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall 21713323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall sentinel = Idx.getZExtValue(); 2172770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2173770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 21743323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned nullPos = 0; 2175770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 21767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 2177770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 2178ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2179ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 2180fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 21813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 2182770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2183770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2184770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 2185bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21863323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 2187770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 2188770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 2189fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 2190fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 2191770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2192770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2193770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2194770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 219587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 21963323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 2197897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 2198897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 2199897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 2200897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 2201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2202897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 22033bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2204770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2205bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 220687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 2207770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 22083bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 2209770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 22102f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2211a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } else if (BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 2212a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman if (!BD->isVariadic()) { 2213a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1; 2214a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman return; 2215a0b2ba1d0ec27240f922c95b5acd8df905e3d3e0Eli Friedman } 221687c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 22172f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 2218daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 221987c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 2220f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 22212f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 22223bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 22233bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 22242f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 22252f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2226ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 22272f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2228883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 22292f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 22302f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 2231770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 2232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2233883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 2234770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 2235770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 2236768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 2237f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 2238770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 2239770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 22401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 2241026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 22421731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2243026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 2244026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 2245f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 2246026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2247883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 2248026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 2249026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 2250bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2251f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 2252f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2253f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 2254f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 2255f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 2256f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 2257f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 2258f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 2259f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 2260f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 2261f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 2262f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 2263768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 2264026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 2265026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 22661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 22676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 226887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 226987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 22706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 227387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 227413c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian if (isa<CXXRecordDecl>(D)) { 227513c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 227613c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian return; 227713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian } 227887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 227987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 2280f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 2281f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 2282f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 228387c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 2284332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 2285332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 2286332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 228787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 22886e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 22896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 2290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2291768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 22926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 22936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 22941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 22956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 22961731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 22976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 22981731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 22996e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 23006e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 23016e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 23020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 23030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 23040a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 23050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 23060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 2307def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 2308bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 230990eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 2310def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 2311def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 2312c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2313883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 23146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 23156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 23166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 23176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 2318768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 23196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 23206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 23211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D, 23221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 23236f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 23241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 3)) 23256f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 23266f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 23276f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 23286f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 23297a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 23306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 2331ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 2332ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 23336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 23346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 23356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 23366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 23376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 23386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 2339768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 2340cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 23416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 23426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 23436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 2344599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaSectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range, 2345599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola StringRef Name) { 2346420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) { 2347420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola if (ExistingAttr->getName() == Name) 2348599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2349420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section); 2350420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola Diag(Range.getBegin(), diag::note_previous_attribute); 2351599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2352420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola } 2353599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) SectionAttr(Range, Context, Name); 2354420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola} 2355420efd83934ee78f04d73880e2ed1b7fdef3328cRafael Espindola 23561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 235717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 23581731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 235917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 236017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 236117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 236217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 23637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2364797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 236517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 2366797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 236717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 236817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 23691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2370797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 2371bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2372a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 2373a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2374a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 2375797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 2376797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 23771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2378a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 2379a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2380a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2381a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 2382a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 2383599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), 2384599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola SE->getString()); 2385599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2386599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 238717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 238817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 23896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 23916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2392831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 23933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2396b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 239787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2398b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2399ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2400b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2401768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2402b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2406232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2407831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 24083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2409232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2410232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2411bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 241287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2413b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2414ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2415b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2416768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2417b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2418232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2419232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 24201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2421232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 24221731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2423232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2424bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2425768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2426232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2427232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 24281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2429bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2430f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2431f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2432f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2434f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2435f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2436f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2437f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2438bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 243987c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2440bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2441f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2442f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2443f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2444f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2445bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2446f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2447c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2448f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2449f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2450f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2451f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2452f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2453f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2454f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2455f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2457f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2458f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2459f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2460f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2461f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2462f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2463f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2464f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2465f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2466f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2467f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2468f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2469f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2470f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 247289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 247389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 247489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 247589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2476b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2477b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2478f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 247989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 248089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 248189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 248289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2483bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2484768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 24855f2987c11491edb186401d4e8eced275f0ea7c5eEli Friedman S.MarkFunctionReferenced(Attr.getParameterLoc(), FD); 2486f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2487f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2488bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2489bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 24901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 24911731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 24925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 24931731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 249487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 24955b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2496883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 24975b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 24985b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 249907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 250007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 250107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 250287c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 250387c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 25045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 250507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 25065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 25077a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 25085b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2509ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2510ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 25115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 25125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 25135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 25145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2515bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 25175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 25185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 25195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 25205b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2521bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2523bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 252407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 252507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 252607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 252707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 252807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 252907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 253007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 253107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 253207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 25335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 253487c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2535bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 25375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 25385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 25395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 25406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 25415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 25425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 25445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 25455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2546bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 254787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 25485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 25495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 25505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 25516217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 25525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 25535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2554bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 25555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 25565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2557bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2558bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 256007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 25615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 25625b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 25632b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 25642b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 25652b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 25662b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 25672b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 25683c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 25692b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 25702b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 25712b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 25722b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 25732b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 25745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 2575c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer return llvm::StringSwitch<FormatAttrKind>(Format) 2576c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer // Check for formats that get handled specially. 2577c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("NSString", NSStringFormat) 2578c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("CFString", CFStringFormat) 2579c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("strftime", StrftimeFormat) 2580c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer 2581c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer // Otherwise, check for supported formats. 2582c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat) 2583c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) 2584c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Case("kprintf", SupportedFormat) // OpenBSD. 2585c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer 2586c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) 2587c51bb99ef9daa17084dea688400b40322289aefeBenjamin Kramer .Default(InvalidFormat); 25882b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 25892b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2590521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2591521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 25921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 25931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 25944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!S.getLangOpts().CPlusPlus) { 2595521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2596521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2597521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2598521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 259987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2600b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2601b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2602b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2603b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 260487c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2605b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2606b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2607b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2608b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2609b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2610b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2611b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 2612b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2613521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2614521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2615521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2616521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2617521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 26187a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 2619b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2620521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2621521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2622521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2623521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2624521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2625521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2626521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2627521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 26289f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2629521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2630521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2631521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2632521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2633521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2634521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2635768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2636f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2637521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2638521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2639599f1b7100745efacb7ded6c176cb7feade114a5Rafael EspindolaFormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format, 2640599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola int FormatIdx, int FirstArg) { 2641bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // Check whether we already have an equivalent format attribute. 2642bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola for (specific_attr_iterator<FormatAttr> 2643bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola i = D->specific_attr_begin<FormatAttr>(), 2644bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola e = D->specific_attr_end<FormatAttr>(); 2645bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola i != e ; ++i) { 2646bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola FormatAttr *f = *i; 2647bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola if (f->getType() == Format && 2648bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->getFormatIdx() == FormatIdx && 2649bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->getFirstArg() == FirstArg) { 2650bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // If we don't have a valid location for this attribute, adopt the 2651bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola // location. 2652bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola if (f->getLocation().isInvalid()) 2653bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola f->setRange(Range); 2654599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return NULL; 2655bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola } 2656bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola } 2657bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola 2658599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, 2659599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FirstArg); 2660bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola} 2661bf9da1f8292bb66720ada94a050ede9dca17f60aRafael Espindola 2662bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 26641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 26656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2666545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2667fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 26683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 26696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 26716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2672545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 26733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 26746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 26766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 267787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2678fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2679883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 26806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 26816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 26826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 268307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 268407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 268587c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 268687c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 26876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 26886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 26906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 26916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 26922b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 26932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 26942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 26952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 26962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 26973c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 26983c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 26993c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 27003c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 27012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2702fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 270301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 27046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 27087a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2709803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2710ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2711ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2712fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 27133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 27146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2718fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 27193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 27206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 27246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2725bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 27264a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 27274a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 272807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 272907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 273007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 27314a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 27324a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 27334a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 27344a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 27351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 273787c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 27386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27392b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2740085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2741fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2742fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2744085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 27452b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2746390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2747390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2748803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2749390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2750fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2751fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 27526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2753bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 27546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 27556217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2756390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2757fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2758fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 27596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 27637a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2765ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2766ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2767fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 27683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 27696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 27736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 277487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 27756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 27766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 277787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 27786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 27833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 27842b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 27856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 2786fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2787fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 27886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 27916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 2792fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 27933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 27946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 27956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 27966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2797599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format, 2798599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola Idx.getZExtValue(), 2799599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola FirstArg.getZExtValue()); 2800599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola if (NewAttr) 2801599f1b7100745efacb7ded6c176cb7feade114a5Rafael Espindola D->addAttr(NewAttr); 28026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 28036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28041b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 28051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 28066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 28071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 28086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 28106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28110c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 28120c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 281387c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 28140c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 28150c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 28160c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 281787c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 28180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 28190c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 2820fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2821883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 28226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 28246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28255e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall if (!RD->isCompleteDefinition()) { 2826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 28270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 28280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 28290c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 28300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 283117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 283217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 28330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 28340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 28350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 28360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2837bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 2838581deb3da481053c4993c7600f97acf7768caac5David Blaikie FieldDecl *FirstField = *Field; 28390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 284090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2841bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 284290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 284390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 28440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 28450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2846bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 28470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 28480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 28490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 28500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 28510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 28520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 28530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 28540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2855bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 28560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 2857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 28580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 28590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 28600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 2861bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 28620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 28630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 2864bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 2865bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 2866bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 28676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2868768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 28696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 28706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 28726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 28731731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 28746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 28767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2877797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2878bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 28796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 28806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 28816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 2882797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 28836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 28846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 288577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 288677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Don't duplicate annotations that are already set. 288777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge for (specific_attr_iterator<AnnotateAttr> 288877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge i = D->specific_attr_begin<AnnotateAttr>(), 288977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 289077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge if ((*i)->getAnnotation() == SE->getString()) 289177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return; 289277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 2893768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 2894f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 28956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 28966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 28986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2899545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 29003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 29016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2903bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2904bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 2905bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 2906bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 29076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2908545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2909768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 29104ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 29114ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 29124ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2913768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 29144ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 29154ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2916768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 29170b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne // FIXME: Handle pack-expansions here. 29180b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne if (DiagnoseUnexpandedParameterPack(E)) 29190b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne return; 29200b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne 29214ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 29224ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2923768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 29246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 29256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2927768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis SourceLocation AttrLoc = AttrRange.getBegin(); 2928cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 292949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 2930ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor ExprResult ICE 2931ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor = VerifyIntegerConstantExpression(E, &Alignment, 2932ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor diag::err_aligned_attribute_argument_not_int, 2933ab41fe914f63bb470dfa7e400876ada72f57a931Douglas Gregor /*AllowFold*/ false); 2934282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith if (ICE.isInvalid()) 293549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 2936396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 29374ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 29384ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2939396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2940396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2941396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2942282e7e66748cc6dd14d6f7f2cb52e5373c531e61Richard Smith D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take())); 2943cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2944cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2945768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2946cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2947cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2948768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2949cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 29506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2952d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 2953bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2954fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2955bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2956bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2957bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 29581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 29631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 29651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2966fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2967fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 29690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2971fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2972210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 29735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 2974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2976210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2977210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2978fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2979fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2980fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 298173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2982210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2983fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 298473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 298573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 298673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 298773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 298873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 298973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 299073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 299173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 299273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 299373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 299473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 299573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 299673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 299773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 299873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 299973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3001fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 3002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 3003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 3004210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 3005bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3006210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 3007bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 3008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 3010210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 3011bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 3012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 3016162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 3017fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 3018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 3019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 3020fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 3021fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 3022768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << "mode" << Attr.getRange(); 3023fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3024fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 302573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 3026183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 302773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 302873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 30292ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 303073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 303173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 303273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 303373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 303473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 303573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 303673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 303773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 303873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 3039390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 3040390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 3041390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 3042390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 3043f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 3044f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 3045fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 3046fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 3047fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 30483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 3049fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3050fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 30513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 3052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 3053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 305473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 305573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 305673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 305773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 30590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 3060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 30610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 3062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 306473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 306573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 306673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 306773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 3068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 30690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 3070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 30710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 3072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3073fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 3074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 30750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 3076fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 30770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 3078fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 30790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 3080fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 3081fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 3082fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 30830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 3084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 3085bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 3086aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 3087aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 3088aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 3089fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 3090bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 3091aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 3092aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 3093aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 3094fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 309573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 309673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 309773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 3098f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 3099f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 3100f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 3101f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 3102f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 3103f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 3104f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 3105f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 3106f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 310773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 3108fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3109fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 311073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 311173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 3112fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 3113fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 3114fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 3115162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 3116ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 3117a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 3118ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 3119fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 3120fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 31210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 31221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3123d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 31241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3125d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 3126e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 312787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 3128d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3129883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 3130d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 3131d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 3132bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3133768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 3134d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 3135d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 31361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 31375bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 31381731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 31395bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 31401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 314287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 31435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3144883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 31455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 31465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 3147bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3148768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 31495bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 31505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 31511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 31521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 31537255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 31541731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 31557255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 31561731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 31577255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 315887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 31597255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3160883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 31617255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 31627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 31637255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 3164768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 3165f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 31667255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 31677255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 31681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3169ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3170ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 3171831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 3172ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3173ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3174ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3175ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 317687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 3177ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3178883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 3179ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3180ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3181ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3182768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 3183ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3184ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 3185ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3186ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3187ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 31881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3189ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3190ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 3191ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 3192ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3193ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3194ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3195ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 319687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 3197ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3198883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 3199ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3200ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3201ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3202768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 3203ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3204ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 3205ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3206ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3207ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 32081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3209ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3210ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 32111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3212ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3213ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 321487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 3215ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3216883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 3217ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3218ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3219ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 322087c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 32212c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 3222723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 32232c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 32242c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 32252c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 32262c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 32272c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 32282c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 32292c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 32302c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 32312c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 32322c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 32332c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 32342c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 3235768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 3236ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3237ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 3238ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3239ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3240ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 32411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3242ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3243ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 32441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3245ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 32461731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3247ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 324887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 3249ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3250883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 3251ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3252ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3253ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3254768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 3255ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3256ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 3257ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3258ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3259ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 32601b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3261ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 3262ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 32631731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 3264ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 32651731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 3266ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 326787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 3268ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3269883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 3270ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 3271ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3272ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 3273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 3274ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 3275ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 3276ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 3277ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 3278ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 32791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 328026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 32811731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 328226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 3283bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 328487c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 3285c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 328626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3287883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 328826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 328926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 3290bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 32910130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 3292cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 3293c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 3294c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 3295bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3296768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 329726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 329826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 32991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 330087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3301711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 330287c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 3303e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 3304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 330587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 3306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3307e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 330887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 330987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 331087c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 331487c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3315e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 3316768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 3317e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3318e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 3319768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 3320e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 3321f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 3322768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 332304633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 3324e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 3325768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 3326e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 332752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3328768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 332952fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 3330414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 333187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *Arg = Attr.getArg(0); 3332414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 33335cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 333487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3335414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 333687c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3337414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3338414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3339414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 33405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3341414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 3342414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") 3343414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 3344414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else if (StrRef == "aapcs-vfp") 3345414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 3346414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else { 334787c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 334887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3349414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 3350414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3351414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 3352768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 3353414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3354e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 3355e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 3356e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 3357e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 3358e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 33591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 336056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 3361768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 3362f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 3363f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 3364711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 3365711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 3366711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3367711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3368831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if ((attr.getNumArgs() != 0 && 3369831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 3370831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek attr.getParameterName()) { 3371711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3372711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 3373711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3374ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 337555d3aaf9a537888734762170823daf750ea9036dEli Friedman 3376414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 3377414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 3378711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 3379711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 3380711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 3381711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 3382711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 3383711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 3384414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 3385414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 3386414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 33875cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3388414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3389414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 3390414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 3391414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 3392414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3393414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 33945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3395414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 3396414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 3397414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3398414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 3399414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 3400414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3401414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3402414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // FALLS THROUGH 3403414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 34047530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("unexpected attribute kind"); 3405711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3406711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3407711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3408711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3409711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 34101b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 341187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3412711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3413711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 341487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3415711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3416711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 341787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 341887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 341987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3420ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3421ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 342255d3aaf9a537888734762170823daf750ea9036dEli Friedman 3423768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3424711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3425711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3426711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3427711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 342887c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 342987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3430711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3431711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 343287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 343387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 343487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3435711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3436711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3437711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 343887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 343955d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3440ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3441711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 344287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 344355d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 344487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3445711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 344655d3aaf9a537888734762170823daf750ea9036dEli Friedman } 344755d3aaf9a537888734762170823daf750ea9036dEli Friedman 3448bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 344987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 345055d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 345187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3452711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 345355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 345455d3aaf9a537888734762170823daf750ea9036dEli Friedman 3455711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3456bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 345787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3458bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 345987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3460711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 346155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 346255d3aaf9a537888734762170823daf750ea9036dEli Friedman 3463711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3464ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3465ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 34661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 34677b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 34687b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 34697b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3470bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3471bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 34727b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 34737b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 34747b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 347587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 34767b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3477883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 34787b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 34797b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 34807b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 34817b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 34827b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 34837b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 34847b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 34857b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 34867b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 34877b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 34887b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 34897b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 34907b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 34917b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 34927b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 34937b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 34947b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 34957b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 34967b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 34977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 34987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 34997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 35007b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 35017b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 35027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 3503768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 35047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 35057b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 35067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 35077b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 35087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 35097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 35107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 35110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3512b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3513b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3514b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3515c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 35166c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 35176c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isObjCObjectPointerType() || 35186c73a2975ba9112787380abd878876336957b3f6Douglas Gregor S.Context.isObjCNSObjectType(type); 3519c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3520c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 35216c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 35226c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isPointerType() || 35236c73a2975ba9112787380abd878876336957b3f6Douglas Gregor isValidSubjectOfNSAttribute(S, type); 3524c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3525c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 35261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 352787c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3528c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 352987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3530768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedParameter; 3531c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3532c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3533c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3534c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 353587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3536c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3537c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3538c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3539c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3540c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3541c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3542c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3543c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 354487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3545768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << cf; 3546c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3547c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3548c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3549c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 3550768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3551c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 3552768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3553c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3554c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 35551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 35561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 355787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 355887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3559768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedMethod; 3560c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3561c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3562c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3563768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3564c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3565c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 35661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 35671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3568b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3569c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3570bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 357187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3572c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 357387c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3574831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian returnType = PD->getType(); 35754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) && 357687c44604325578b8de07d768391c1c9432404f5aChandler Carruth (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3577f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 357887c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3579c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 35805dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 358187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3582768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() 3583883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3584b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3585b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3586bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3587c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3588c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 358987c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 35907530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie default: llvm_unreachable("invalid ownership attribute"); 3591c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3592c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 3593c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 3594c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3595c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3596c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3597c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3598c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 3599c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 3600c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3601c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3602c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3603c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3604c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3605c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 360687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3607768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3608bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 36095dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3610bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 361187c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3612b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3613b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ownership attribute"); 3614c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3615768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3616c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3617c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 361831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3619768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3620f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 362131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 362231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 3623768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3624f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 362531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 3626b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 3627768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3628f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3629b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3630b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3631768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3632f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3633b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3634b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3635b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3636b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3637dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3638dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3639dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3640dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3641dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3642dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 364394d55d7ecdd693788a8f3910a0da1b5ecdaa8a86Fariborz Jahanian if (!method) { 36440e78afbb15c6f51932e562e620f714c37cf914e6Fariborz Jahanian S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3645f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; 3646dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3647dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3648dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3649dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3650dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 3651f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian 3652f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian if (!resultType->isReferenceType() && 3653f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3654dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3655dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3656dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3657dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3658dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3659dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3660dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3661dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3662dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3663768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3664dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3665dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 36668dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer. 36678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 36688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!isa<FunctionDecl>(D)) { 36698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3670f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << A.getRange() << A.getName() << ExpectedFunction; 36718dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 36728dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 36738dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 36748dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 36758dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 36768dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Check whether there's a conflicting attribute already present. 36778dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Attr *Existing; 36788dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 36798dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFUnknownTransferAttr>(); 36808dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 36818dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFAuditedTransferAttr>(); 36828dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 36838dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (Existing) { 36848dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 36858dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getName() 36868dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 36878dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << Existing->getRange(); 36888dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 36898dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 36908dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 36918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // All clear; add the attribute. 36928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 36938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 36948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 36958dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 36968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 36978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 36988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 36998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 37008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3701fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 3702fe98da0fa352462c02db037360788748f95466f7John McCall const AttributeList &Attr) { 3703fe98da0fa352462c02db037360788748f95466f7John McCall RecordDecl *RD = dyn_cast<RecordDecl>(D); 3704fe98da0fa352462c02db037360788748f95466f7John McCall if (!RD || RD->isUnion()) { 3705fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3706f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedStruct; 3707fe98da0fa352462c02db037360788748f95466f7John McCall } 3708fe98da0fa352462c02db037360788748f95466f7John McCall 3709fe98da0fa352462c02db037360788748f95466f7John McCall IdentifierInfo *ParmName = Attr.getParameterName(); 3710fe98da0fa352462c02db037360788748f95466f7John McCall 3711fe98da0fa352462c02db037360788748f95466f7John McCall // In Objective-C, verify that the type names an Objective-C type. 3712fe98da0fa352462c02db037360788748f95466f7John McCall // We don't want to check this outside of ObjC because people sometimes 3713fe98da0fa352462c02db037360788748f95466f7John McCall // do crazy C declarations of Objective-C types. 37144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (ParmName && S.getLangOpts().ObjC1) { 3715fe98da0fa352462c02db037360788748f95466f7John McCall // Check for an existing type with this name. 3716fe98da0fa352462c02db037360788748f95466f7John McCall LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 3717fe98da0fa352462c02db037360788748f95466f7John McCall Sema::LookupOrdinaryName); 3718fe98da0fa352462c02db037360788748f95466f7John McCall if (S.LookupName(R, Sc)) { 3719fe98da0fa352462c02db037360788748f95466f7John McCall NamedDecl *Target = R.getFoundDecl(); 3720fe98da0fa352462c02db037360788748f95466f7John McCall if (Target && !isa<ObjCInterfaceDecl>(Target)) { 3721fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 3722fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(Target->getLocStart(), diag::note_declared_at); 3723fe98da0fa352462c02db037360788748f95466f7John McCall } 3724fe98da0fa352462c02db037360788748f95466f7John McCall } 3725fe98da0fa352462c02db037360788748f95466f7John McCall } 3726fe98da0fa352462c02db037360788748f95466f7John McCall 3727fe98da0fa352462c02db037360788748f95466f7John McCall D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 3728fe98da0fa352462c02db037360788748f95466f7John McCall ParmName)); 3729fe98da0fa352462c02db037360788748f95466f7John McCall} 3730fe98da0fa352462c02db037360788748f95466f7John McCall 37311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 37321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 373387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3734f85e193739c953358c865005855253af4f68a497John McCall 373587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3736f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3737f85e193739c953358c865005855253af4f68a497John McCall} 3738f85e193739c953358c865005855253af4f68a497John McCall 37391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 37401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 374187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 374287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3743f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor << Attr.getRange() << Attr.getName() << ExpectedVariable; 3744f85e193739c953358c865005855253af4f68a497John McCall return; 3745f85e193739c953358c865005855253af4f68a497John McCall } 3746f85e193739c953358c865005855253af4f68a497John McCall 374787c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 3748f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 3749f85e193739c953358c865005855253af4f68a497John McCall 3750f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 3751f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 375287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3753f85e193739c953358c865005855253af4f68a497John McCall << type; 3754f85e193739c953358c865005855253af4f68a497John McCall return; 3755f85e193739c953358c865005855253af4f68a497John McCall } 3756f85e193739c953358c865005855253af4f68a497John McCall 3757f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3758f85e193739c953358c865005855253af4f68a497John McCall 3759f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 3760f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 3761f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3762f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 3763f85e193739c953358c865005855253af4f68a497John McCall 3764f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 3765f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 3766f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 3767f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 3768f85e193739c953358c865005855253af4f68a497John McCall break; 3769f85e193739c953358c865005855253af4f68a497John McCall 3770f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 3771f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 3772f85e193739c953358c865005855253af4f68a497John McCall break; 3773f85e193739c953358c865005855253af4f68a497John McCall 3774f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 3775f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 377687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3777f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 3778f85e193739c953358c865005855253af4f68a497John McCall break; 3779f85e193739c953358c865005855253af4f68a497John McCall } 3780f85e193739c953358c865005855253af4f68a497John McCall 378187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 3782768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3783f85e193739c953358c865005855253af4f68a497John McCall} 3784f85e193739c953358c865005855253af4f68a497John McCall 3785f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 37869428772f16e379bcad35254251f96e3d1077c730Aaron Ballman switch (Attr.getKind()) { 37879428772f16e379bcad35254251f96e3d1077c730Aaron Ballman default: 37889428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return false; 37899428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllimport: 37909428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_dllexport: 37919428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_uuid: 37929428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_deprecated: 37939428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noreturn: 37949428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_nothrow: 37959428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_naked: 37969428772f16e379bcad35254251f96e3d1077c730Aaron Ballman case AttributeList::AT_noinline: 37979428772f16e379bcad35254251f96e3d1077c730Aaron Ballman return true; 37989428772f16e379bcad35254251f96e3d1077c730Aaron Ballman } 379911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 380011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 380111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 380211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 380311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 380411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 38051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 380662ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 380711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 38081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 380911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 38101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 381111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 381211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 38135cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3814d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3815d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 3816d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3817d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3818d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 38195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3820d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3821d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3822d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 3823f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor 3824d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 3825d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 3826d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3827d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3828d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3829d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 3830d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3831d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3832d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3833d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3834f6b8b585596f6cf7924fecc5b7a741d4b45809dcDouglas Gregor // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3835d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 38365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 3837f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 3838f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 3839f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 3840f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 3841d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 3842d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 3843d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3844d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3845d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3846d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 3847d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3848d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3849d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3850d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 3851d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 385211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 3853768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 385411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 3855d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 385611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3857f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 3858f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 3859c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3860c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (S.LangOpts.MicrosoftExt) { 3861c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall AttributeList::Kind Kind = Attr.getKind(); 3862c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (Kind == AttributeList::AT_single_inheritance) 3863c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3864c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context)); 3865c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall else if (Kind == AttributeList::AT_multiple_inheritance) 3866c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3867c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context)); 3868c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall else if (Kind == AttributeList::AT_virtual_inheritance) 3869c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3870c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context)); 3871c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } else 3872c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3873c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 3874c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 3875c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallstatic void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3876c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (S.LangOpts.MicrosoftExt) { 3877c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall AttributeList::Kind Kind = Attr.getKind(); 3878c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (Kind == AttributeList::AT_ptr32) 3879c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3880c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context)); 3881c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall else if (Kind == AttributeList::AT_ptr64) 3882c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3883c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context)); 3884c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall else if (Kind == AttributeList::AT_w64) 3885c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall D->addAttr( 3886c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ::new (S.Context) Win64Attr(Attr.getRange(), S.Context)); 3887c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } else 3888c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3889c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 3890c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 3891adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencerstatic void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 3892adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer if (S.LangOpts.MicrosoftExt) 3893adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context)); 3894adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer else 3895adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3896adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer} 3897adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer 3898b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 38990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 39000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 39010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 39021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 39031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 390460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 39051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 39061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 39071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 390860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 390960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 391060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 391160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 3912e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 39131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 39141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3915803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 3916e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_ibaction: handleIBAction(S, D, Attr); break; 3917e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutlet: handleIBOutlet(S, D, Attr); break; 3918e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_iboutletcollection: 39191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 3920803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 3921207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 3922ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 39236e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 39244211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 39254211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 3926bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 3927bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 3928803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 392960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 393060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 393160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 393260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 393360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 393460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 39351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 39361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3937587de5be6bc8b9d046015b20079d45ac4b98bc14Nuno Lopes case AttributeList::AT_alloc_size: handleAllocSizeAttr (S, D, Attr); break; 3938bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 39391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 3940b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 39411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 39421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 39431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3944bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 39451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 39461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 39471b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 39481b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 3949bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer case AttributeList::AT_deprecated: 3950bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer handleAttrWithMessage<DeprecatedAttr>(S, D, Attr, "deprecated"); 3951bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer break; 39521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 39533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 39541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 39553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 39561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 39571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 39581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 39591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 39607b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 39611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 39627b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 39631b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 39641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 39651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 39661b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 39671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3968dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 3969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 3970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 39711b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 3972ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer case AttributeList::AT_cold: handleColdAttr (S, D, Attr); break; 3973ee409a916e9b97ed6bc2f48d8d6aac6b8b773d7bBenjamin Kramer case AttributeList::AT_hot: handleHotAttr (S, D, Attr); break; 39741b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 39751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 39761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 39771b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 39781b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3979b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3980b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis case AttributeList::AT_objc_ownership: 39811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 3982f85e193739c953358c865005855253af4f68a497John McCall case AttributeList::AT_objc_precise_lifetime: 39831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3984f85e193739c953358c865005855253af4f68a497John McCall 3985dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall case AttributeList::AT_objc_returns_inner_pointer: 3986dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3987dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3988fe98da0fa352462c02db037360788748f95466f7John McCall case AttributeList::AT_ns_bridged: 3989fe98da0fa352462c02db037360788748f95466f7John McCall handleNSBridgedAttr(S, scope, D, Attr); break; 3990fe98da0fa352462c02db037360788748f95466f7John McCall 39918dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_audited_transfer: 39928dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_unknown_transfer: 39938dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall handleCFTransferAttr(S, D, Attr); break; 39948dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3995b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 3996c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 39971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3998c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 39991b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 4000c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 4001c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 400231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 400331c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 4004b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 4005b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 40061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 4007b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 4008e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_reqd_work_group_size: 40091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleReqdWorkGroupSize(S, D, Attr); break; 40106f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 4011521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 40121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 4013521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 40141b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 40151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 4016bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer case AttributeList::AT_unavailable: 4017bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer handleAttrWithMessage<UnavailableAttr>(S, D, Attr, "unavailable"); 4018bc3260d20bd075566fa87a4182e0760126f79c1eBenjamin Kramer break; 4019e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_objc_arc_weak_reference_unavailable: 4020742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian handleArcWeakrefUnavailableAttr (S, D, Attr); 4021742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 4022b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard case AttributeList::AT_objc_root_class: 4023b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard handleObjCRootClassAttr(S, D, Attr); 4024b2f6820773aabff3c5c9e0dbb1cbbbda0d80c41fPatrick Beard break; 402571207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek case AttributeList::AT_objc_requires_property_definitions: 402671207fc0470e1eee40a2951cd5cc3ff47725b755Ted Kremenek handleObjCRequiresPropertyDefsAttr (S, D, Attr); 4027e23dcf3524fe01208cc79e707412f0a5dd8eed7bFariborz Jahanian break; 40281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 4029f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola case AttributeList::AT_returns_twice: 4030f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola handleReturnsTwiceAttr(S, D, Attr); 4031f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola break; 40321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 40331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 40341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 4035026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 40361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 40371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 40381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 4039803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 40401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 4041803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 40420db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 40431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 40440db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 4045d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 40461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 4047d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 4048e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han case AttributeList::AT_NSObject: handleObjCNSObject (S, D, Attr); break; 40491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 40501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 40511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 40521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 40531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 40541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 40551b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 40561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 4057bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 405805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 405905f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 40607255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 40611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 40627255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 406304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 406404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 406504a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 4066f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 406752fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 4068414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: 40691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 407004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 4071f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 40721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 4073f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 4074c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 4075c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall // Microsoft attributes: 4076c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_ms_struct: 4077c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handleMsStructAttr(S, D, Attr); 4078c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 407911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 40801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 408111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 4082c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_single_inheritance: 4083c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_multiple_inheritance: 4084c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_virtual_inheritance: 4085c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handleInheritanceAttr(S, D, Attr); 4086c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 4087c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_w64: 4088c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_ptr32: 4089c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall case AttributeList::AT_ptr64: 4090c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall handlePortabilityAttr(S, D, Attr); 4091c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall break; 4092adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer case AttributeList::AT_forceinline: 4093adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer handleForceInlineAttr(S, D, Attr); 4094adc6cbf5b502f1b58078455ab4fca66c7daac239Michael J. Spencer break; 4095fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4096fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 4097fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_guarded_var: 4098fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 4099fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 4100fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_pt_guarded_var: 4101fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 4102fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 4103fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_scoped_lockable: 4104fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr, /*scoped = */true); 4105fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 410671efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany case AttributeList::AT_no_address_safety_analysis: 410771efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany handleNoAddressSafetyAttr(S, D, Attr); 410871efba0bbafaefab14419fbd284efff5f7acade7Kostya Serebryany break; 4109fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_no_thread_safety_analysis: 4110fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 4111fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 4112fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_lockable: 4113fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 4114fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 4115db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_guarded_by: 4116db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 4117db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4118db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_pt_guarded_by: 4119db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr, /*pointer = */true); 4120db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4121db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_lock_function: 4122db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr, /*exclusive = */true); 4123db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4124db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_locks_required: 4125db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 4126db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4127db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_trylock_function: 4128db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 4129db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4130db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_lock_returned: 4131db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 4132db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4133db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_locks_excluded: 4134db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 4135db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4136db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_lock_function: 4137db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr); 4138db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4139db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_locks_required: 4140db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr); 4141db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4142db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_trylock_function: 4143db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr); 4144db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4145db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_unlock_function: 4146db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 4147db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4148db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_before: 4149db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */true); 4150db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4151db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_after: 4152db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */false); 4153db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 4154fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 415682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 415782d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 415882d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 41597d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 41607d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 4161803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 4162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 4163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 4164803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 416560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 416660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 416760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 416860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 41691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 41701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 417160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 417260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 417360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 417460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 417560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 417660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 417760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 417860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 417960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 41801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 418160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 418260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 41831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 418460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 418560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 4186803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 4187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 4188f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 418960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 419060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 419111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 419298ae834a3e289f84f0765d0d0ca7ff22ccaba458Rafael Espindola ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 41939b79fc9c57dc9d541c2a5737c3e2c24cc68d485dRafael Espindola } 419411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 419511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 419611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 419711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 419860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 419911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 4200dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 420111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 4202803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 4203803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 4204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 42055f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access 42065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier. 42075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 42085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen const AttributeList *AttrList) { 42095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen for (const AttributeList* l = AttrList; l; l = l->getNext()) { 42105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (l->getKind() == AttributeList::AT_annotate) { 42115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen handleAnnotateAttr(*this, ASDecl, *l); 42125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } else { 42135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 42145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return true; 42155f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 42165f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 42175f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 42185f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return false; 42195f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen} 42205f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 4221e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it 4222e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about. 4223e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 4224e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for ( ; A; A = A->getNext()) { 4225e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall // Only warn if the attribute is an unignored, non-type attribute. 4226e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->isUsedAsTypeAttr()) continue; 4227e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::IgnoredAttribute) continue; 4228e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4229e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::UnknownAttribute) { 4230e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 4231e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 4232e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } else { 4233e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 4234e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 4235e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 4236e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 4237e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 4238e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4239e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being 4240e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes 4241e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it. 4242e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 4243e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 4244e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getAttributes()); 4245e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 4246e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 4247e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 4248e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 4249e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 42501dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// \#pragma weak needs a non-definition decl and source may not have one. 4251900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 4252900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 42537b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 4254e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 4255e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 4256900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 4257900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 4258900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 4259900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 4260900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 4261900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 4262900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 4263900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 4264900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 4265900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 4266900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 4267900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 4268900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 4269900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 4270900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 4271c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 4272900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 4273900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 4274900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 4275900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 4276900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 4277900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 4278900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 4279900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 4280900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 4281900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 4282900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 4283900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 42844278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie NewFD->setParams(Params); 4285b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 4286e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 4287e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 4288ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 4289a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 429016573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 429116573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 4292b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 4293b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 4294c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 4295b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 4296e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4297e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 4298e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 4299e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 43001dfbd92c83699820bfaa352e83083124e34fc9dcJames Dennett/// DeclApplyPragmaWeak - A declaration (maybe definition) needs \#pragma weak 4301e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 43027b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 4303c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 4304c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 4305c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 4306c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 4307900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 4308cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 4309cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 4310cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 4311c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 4312c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 4313c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 4314c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 4315c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 4316c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 4317c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 4318c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 4319cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 4320e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4321e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 4322e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 43230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 43240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 43250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 432660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 432760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 4328d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 4329d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 433031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 433131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 433231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 433331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 433431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 433531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 433631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 433731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 433831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 433931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 434031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 434131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 4342d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 4343e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4344e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4345e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 4346e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 43470744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 43487f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 434960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 4350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 43510744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 43520744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 43530744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 43540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 43550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 43560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 435760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 4358bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 43590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 43600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 436160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 43620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 436354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 4364f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 4365f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 4366f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 4367f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 4368f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 4369a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian // Function declarations in sys headers will be marked unavailable. 4370a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 4371a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian !isa<FunctionDecl>(decl)) 4372f85e193739c953358c865005855253af4f68a497John McCall return false; 4373f85e193739c953358c865005855253af4f68a497John McCall 4374f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 4375f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 4376f85e193739c953358c865005855253af4f68a497John McCall} 4377f85e193739c953358c865005855253af4f68a497John McCall 4378f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 4379f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 4380f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 4381f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 4382f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 4383f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 4384f85e193739c953358c865005855253af4f68a497John McCall return; 4385f85e193739c953358c865005855253af4f68a497John McCall } 43864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (S.getLangOpts().ObjCAutoRefCount) 4387175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 438848d798ce32447607144db70a484cdb99c1180663Benjamin Kramer // FIXME: we may want to suppress diagnostics for all 4389175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // kind of forbidden type messages on unavailable functions. 4390175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (FD->hasAttr<UnavailableAttr>() && 4391175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.getForbiddenTypeDiagnostic() == 4392175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag::err_arc_array_param_no_ownership) { 4393175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.Triggered = true; 4394175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian return; 4395175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4396175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 4397f85e193739c953358c865005855253af4f68a497John McCall 4398f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 4399f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 4400f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 4401f85e193739c953358c865005855253af4f68a497John McCall} 4402f85e193739c953358c865005855253af4f68a497John McCall 44039257664568bf375b7790131a84d9a4fa30a5b7e3John McCallvoid Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) { 44049257664568bf375b7790131a84d9a4fa30a5b7e3John McCall assert(DelayedDiagnostics.getCurrentPool()); 440513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool(); 44069257664568bf375b7790131a84d9a4fa30a5b7e3John McCall DelayedDiagnostics.popWithoutEmitting(state); 44079257664568bf375b7790131a84d9a4fa30a5b7e3John McCall 44089257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // When delaying diagnostics to run in the context of a parsed 44099257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // declaration, we only want to actually emit anything if parsing 44109257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // succeeds. 44119257664568bf375b7790131a84d9a4fa30a5b7e3John McCall if (!decl) return; 44129257664568bf375b7790131a84d9a4fa30a5b7e3John McCall 44139257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // We emit all the active diagnostics in this pool or any of its 44149257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // parents. In general, we'll get one pool for the decl spec 44159257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // and a child pool for each declarator; in a decl group like: 44169257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // deprecated_typedef foo, *bar, baz(); 44179257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // only the declarator pops will be passed decls. This is correct; 44189257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // we really do need to consider delayed diagnostics from the decl spec 44199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // for each of the different declarations. 442013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall const DelayedDiagnosticPool *pool = &poppedPool; 44219257664568bf375b7790131a84d9a4fa30a5b7e3John McCall do { 442213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall for (DelayedDiagnosticPool::pool_iterator 44239257664568bf375b7790131a84d9a4fa30a5b7e3John McCall i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) { 44249257664568bf375b7790131a84d9a4fa30a5b7e3John McCall // This const_cast is a bit lame. Really, Triggered should be mutable. 44259257664568bf375b7790131a84d9a4fa30a5b7e3John McCall DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i); 4426eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 44272f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 44282f514480c448708ec382a684cf5e035d3a827ec8John McCall 4429eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 44302f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 4431e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall // Don't bother giving deprecation diagnostics if the decl is invalid. 4432e8c904ff343f440e213b88e6963f5ebfbec7ae60John McCall if (!decl->isInvalidDecl()) 44339257664568bf375b7790131a84d9a4fa30a5b7e3John McCall HandleDelayedDeprecationCheck(diag, decl); 44342f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 44352f514480c448708ec382a684cf5e035d3a827ec8John McCall 44362f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 44379257664568bf375b7790131a84d9a4fa30a5b7e3John McCall HandleDelayedAccessCheck(diag, decl); 44382f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 4439f85e193739c953358c865005855253af4f68a497John McCall 4440f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 44419257664568bf375b7790131a84d9a4fa30a5b7e3John McCall handleDelayedForbiddenType(*this, diag, decl); 4442f85e193739c953358c865005855253af4f68a497John McCall break; 444354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 444454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 44459257664568bf375b7790131a84d9a4fa30a5b7e3John McCall } while ((pool = pool->getParent())); 44462f514480c448708ec382a684cf5e035d3a827ec8John McCall} 44472f514480c448708ec382a684cf5e035d3a827ec8John McCall 444813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Given a set of delayed diagnostics, re-emit them as if they had 444913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// been delayed in the current context instead of in the given pool. 445013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall/// Essentially, this just moves them to the current pool. 445113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCallvoid Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { 445213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool(); 445313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall assert(curPool && "re-emitting in undelayed context not supported"); 445413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall curPool->steal(pool); 445513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall} 445613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall 44572f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 44582f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 44590a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 44602f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 4461c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // A category implicitly has the availability of the interface. 4462c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 4463c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis return CatD->getClassInterface()->isDeprecated(); 44642f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 44652f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 44662f514480c448708ec382a684cf5e035d3a827ec8John McCall} 44672f514480c448708ec382a684cf5e035d3a827ec8John McCall 44689c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 44692f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 44702f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 44712f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 44722f514480c448708ec382a684cf5e035d3a827ec8John McCall 44732f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 4474ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 4475c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 4476ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 4477ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 4478b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian else if (DD.getUnknownObjCClass()) { 4479b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_fwdclass_message) 4480b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian << DD.getDeprecationDecl()->getDeclName(); 4481b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class); 4482b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian } 4483c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 4484c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 4485ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 448654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 448754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 44885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 44898e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 449089ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 449154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 4492eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 4493b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 4494b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian UnknownObjCClass, 4495b0a6615cb9f5e881b81b117017b484fe91112967Fariborz Jahanian Message)); 449654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 449754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 449854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 449954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 45003a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 450154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 4502d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian if (!Message.empty()) { 4503c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 4504c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 4505d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian Diag(D->getLocation(), 4506d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 4507d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian : diag::note_previous_decl) << D->getDeclName(); 4508d6724367519b4f98dcce091854549282c11d70a0Fariborz Jahanian } 45098e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 4510350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian if (!UnknownObjCClass) { 45118e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 4512350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian Diag(D->getLocation(), 4513350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at 4514350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian : diag::note_previous_decl) << D->getDeclName(); 4515350e956532d99ce2e804a478df5b6f1f5e096d88Fariborz Jahanian } 451689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian else { 45178e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 451889ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 451989ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian } 45208e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 452154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 4522