SemaDeclAttr.cpp revision 0bfaf067c294bc4064c2f1aee0bc1c51e861ac65
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 1582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov#include "TargetAttributesSema.h" 166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 17384aff8b94bb0d1ad6c5667b90621e5699815bb2John McCall#include "clang/AST/DeclCXX.h" 18b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski#include "clang/AST/DeclTemplate.h" 19acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 20acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 21f85e193739c953358c865005855253af4f68a497John McCall#include "clang/Basic/SourceManager.h" 22fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2319510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 249c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h" 25fe98da0fa352462c02db037360788748f95466f7John McCall#include "clang/Sema/Lookup.h" 26797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner#include "llvm/ADT/StringExtras.h" 276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 289c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema; 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// These constants match the enumerated choices of 31883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 32b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskienum AttributeDeclKind { 33883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunction, 34883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedUnion, 35883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariableOrFunction, 36883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionOrMethod, 37883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameter, 38883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedParameterOrMethod, 39883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrBlock, 40883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassOrVirtualMethod, 41883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedFunctionMethodOrParameter, 42883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClass, 43883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVirtualMethod, 44883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedClassMember, 45883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedVariable, 46883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall ExpectedMethod, 47db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedVariableFunctionOrLabel, 48db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski ExpectedFieldOrGlobalVar 49883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall}; 50883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall 51e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 52e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 53e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 54e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 5587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic const FunctionType *getFunctionType(const Decl *D, 56a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek bool blocksToo = true) { 576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 5887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const ValueDecl *decl = dyn_cast<ValueDecl>(D)) 596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 6087c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D)) 616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 6287c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D)) 636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 66bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 686217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 69755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 72183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall return Ty->getAs<FunctionType>(); 736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 78d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes/// isFunction - Return true if the given decl has function 79a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// type (function or function-typed variable). 8087c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunction(const Decl *D) { 8187c44604325578b8de07d768391c1c9432404f5aChandler Carruth return getFunctionType(D, false) != NULL; 82a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek} 83a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek 84a18d7d80eb914a48521f0b7b25057fb8a69c4652Ted Kremenek/// isFunctionOrMethod - Return true if the given decl has function 85d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 86d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 8787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethod(const Decl *D) { 8887c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isFunction(D)|| isa<ObjCMethodDecl>(D); 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 9487c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodOrBlock(const Decl *D) { 9587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethod(D)) 96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 9887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 99620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 100620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 101620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 10287c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<BlockDecl>(D); 103620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 104620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 105711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Return true if the given decl has a declarator that should have 106711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// been processed by Sema::GetTypeForDeclarator. 10787c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasDeclarator(const Decl *D) { 108f85e193739c953358c865005855253af4f68a497John McCall // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl. 10987c44604325578b8de07d768391c1c9432404f5aChandler Carruth return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) || 11087c44604325578b8de07d768391c1c9432404f5aChandler Carruth isa<ObjCPropertyDecl>(D); 111711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 112711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 113d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 114d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 115620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 11687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool hasFunctionProto(const Decl *D) { 11787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 11872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 119620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 12087c44604325578b8de07d768391c1c9432404f5aChandler Carruth assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D)); 121d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 122d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 1233568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1243568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 125d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 126d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 127d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 12887c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic unsigned getFunctionOrMethodNumArgs(const Decl *D) { 12987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 13072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 13187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 132d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 13387c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_size(); 1343568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1353568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 13687c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) { 13787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 13872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 13987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 140d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 141bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 14287c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType(); 1433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1443568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 14587c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic QualType getFunctionOrMethodResultType(const Decl *D) { 14687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) 1475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 14887c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->getResultType(); 1495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 15187c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isFunctionOrMethodVariadic(const Decl *D) { 15287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionType *FnTy = getFunctionType(D)) { 15372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 15587c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 156db9a0aec04cfd95830d3745b17b0bab5b87b16d1Ted Kremenek return BD->isVariadic(); 157d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 15887c44604325578b8de07d768391c1c9432404f5aChandler Carruth return cast<ObjCMethodDecl>(D)->isVariadic(); 1593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1613568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 16287c44604325578b8de07d768391c1c9432404f5aChandler Carruthstatic bool isInstanceMethod(const Decl *D) { 16387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) 16407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return MethodDecl->isInstance(); 16507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return false; 16607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth} 16707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 169183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>(); 170b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 172bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 173506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface(); 174506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall if (!Cls) 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 177506b57e8b79d7dc2c367bf2ee7ec95420ad3fc8fJohn McCall IdentifierInfo* ClsName = Cls->getIdentifier(); 178bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 184085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 1856217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 186085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 187085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 188085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1896217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 190085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 191085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 192bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 193085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 194465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara if (RD->getTagKind() != TTK_Struct) 195085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 196085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 197085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 198085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 199085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 200b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has exactly as many args as Num. May 201b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 2021731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruthstatic bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr, 2031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth unsigned int Num) { 2041731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (Attr.getNumArgs() != Num) { 2051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Num; 2061731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return false; 2071731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth } 2081731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2091731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return true; 2101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth} 2111731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 212db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 213b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the attribute has at least as many args as Num. May 214b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// output an error. 215b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr, 216b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int Num) { 217b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (Attr.getNumArgs() < Num) { 218db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num; 219db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return false; 220db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 221db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 222db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return true; 223db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 224db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 225db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski/// 226fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a field or potentially shared global var 227fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a field or potentially shared global variable 228fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 22939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool mayBeSharedVariable(const Decl *D) { 230fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (isa<FieldDecl>(D)) 231fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 23239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const VarDecl *vd = dyn_cast<VarDecl>(D)) 233fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return (vd->hasGlobalStorage() && !(vd->isThreadSpecified())); 234fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 235fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 236fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 237fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 238b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Check if the passed-in expression is of type int or bool. 239b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowskistatic bool isIntOrBool(Expr *Exp) { 240b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = Exp->getType(); 241b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return QT->isBooleanType() || QT->isIntegerType(); 242b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 243b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 244fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 245fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \brief Check if passed in Decl is a pointer type. 246fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// Note that this function may produce an error message. 247fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// \return true if the Decl is a pointer type; false otherwise 248fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski/// 24939997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramerstatic bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) { 25039997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) { 251fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski QualType QT = vd->getType(); 25239997fc2b8d300a85ead0a7d687964c6e63a8110Benjamin Kramer if (QT->isAnyPointerType()) 253fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return true; 254fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type) 255fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName()->getName() << QT; 256fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } else { 257fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl) 258fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName(); 259fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 260fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return false; 261fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 262fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 263b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Checks that the passed in QualType either is of RecordType or points 264b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// to RecordType. Returns the relevant RecordType, null if it does not exit. 2657d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramerstatic const RecordType *getRecordType(QualType QT) { 2667d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const RecordType *RT = QT->getAs<RecordType>()) 267b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return RT; 2687d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2697d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer // Now check if we point to record type. 2707d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer if (const PointerType *PT = QT->getAs<PointerType>()) 2717d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return PT->getPointeeType()->getAs<RecordType>(); 2727d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer 2737d23b4a6e855f156bbd30cf2702ebbeb5bc57028Benjamin Kramer return 0; 274b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 275b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 2763ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \brief Thread Safety Analysis: Checks that the passed in RecordType 2773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// resolves to a lockable object. May flag an error. 278d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramerstatic bool checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 279d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer const RecordType *RT) { 2803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Flag error if could not get record type for this argument. 281d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT) { 2823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_class) 2833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski << Attr.getName(); 2843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return false; 2853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 2863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Flag error if the type is not lockable. 287d77ba899b3ed39aa4bdba22aabc4bcd5ca6effdfBenjamin Kramer if (!RT->getDecl()->getAttr<LockableAttr>()) { 2883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_lockable) 2893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski << Attr.getName(); 2903ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return false; 2913ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski } 2923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return true; 2933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski} 2943ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 295b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting 296b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski/// from Sidx, resolve to a lockable object. May flag an error. 2973ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param Sidx The attribute argument index to start checking with. 2983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// \param ParamIdxOk Whether an argument can be indexing into a function 2993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski/// parameter list. 3003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowskistatic bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 3013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const AttributeList &Attr, 3023ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVectorImpl<Expr*> &Args, 303b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski int Sidx = 0, 304b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool ParamIdxOk = false) { 3053ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) { 306b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski Expr *ArgExp = Attr.getArg(Idx); 3073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 308ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski if (ArgExp->isTypeDependent()) { 309ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski // FIXME -- need to processs this again on template instantiation 310ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski Args.push_back(ArgExp); 311ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski continue; 312ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski } 313b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski QualType ArgTy = ArgExp->getType(); 315b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // First see if we can just cast to record type, or point to record type. 3173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski const RecordType *RT = getRecordType(ArgTy); 318b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3193ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // Now check if we index into a record type function param. 3203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!RT && ParamIdxOk) { 3213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 322b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski IntegerLiteral *IL = dyn_cast<IntegerLiteral>(ArgExp); 323b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if(FD && IL) { 324b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski unsigned int NumParams = FD->getNumParams(); 325b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski llvm::APInt ArgValue = IL->getValue(); 3263ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromOne = ArgValue.getZExtValue(); 3273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski uint64_t ParamIdxFromZero = ParamIdxFromOne - 1; 3283ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) { 329b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range) 330b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << Idx + 1 << NumParams; 331b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return false; 332b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 3333ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType(); 3343ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski RT = getRecordType(ArgTy); 335b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 336b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 337b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, RT)) 339b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return false; 340b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 3413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Args.push_back(ArgExp); 342b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 343b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return true; 344b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski} 345b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 346e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 347e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 348e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 349e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 3503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 3513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 3523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 3533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 354fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, 355fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool pointer = false) { 356fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 357fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 358fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 359fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 360fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 361fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 362fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!mayBeSharedVariable(D)) { 363fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 364b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 365fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 366fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 367fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 368fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer && !checkIsPointer(S, D, Attr)) 369fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 370fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 371fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (pointer) 372768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context)); 373fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 374768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context)); 375fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 376fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 377db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 378b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool pointer = false) { 379db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 380db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 381b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 382db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 383db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 3843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 3853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 386db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 387db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (!mayBeSharedVariable(D)) { 388db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 389b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 390db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 391db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 392db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 393db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer && !checkIsPointer(S, D, Attr)) 394db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 395db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 3963ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 397ed9d84a2112e2bd56befb5f4fa8fc5bdf71fafa3Caitlin Sadowski // FIXME: handle attributes with dependent types 3983ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return; 3993ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 4003ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 4013ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 402b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 403b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 404db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (pointer) 405768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(), 4063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, Arg)); 407db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 408768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg)); 409db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 410db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 411db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 412fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr, 413fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski bool scoped = false) { 414fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 415fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 416fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 417fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 418fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 4191748b1256646cf0752f172c53ad7482f7beed185Caitlin Sadowski // FIXME: Lockable structs for C code. 420fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!isa<CXXRecordDecl>(D)) { 421fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 422fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedClass; 423fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 424fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 425fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 426fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (scoped) 427768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context)); 428fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski else 429768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context)); 430fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 431fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 432fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowskistatic void handleNoThreadSafetyAttr(Sema &S, Decl *D, 433fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski const AttributeList &Attr) { 434fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski assert(!Attr.isInvalid()); 435fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 436fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 0)) 437fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 438fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 439b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 440fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 441fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 442fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski return; 443fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski } 444fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 445768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(), 446fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski S.Context)); 447fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski} 448fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 449db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 450db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski bool before) { 451db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 452db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 453b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 454db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 455db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 456db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // D must be either a member field or global (potentially shared) variable. 457b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski ValueDecl *VD = dyn_cast<ValueDecl>(D); 458b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!VD || !mayBeSharedVariable(D)) { 459db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 460b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName() << ExpectedFieldOrGlobalVar; 461db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 462db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 463db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 464b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // Check that this attribute only applies to lockable types 465b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski QualType QT = VD->getType(); 466b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!QT->isDependentType()) { 467b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const RecordType *RT = getRecordType(QT); 468b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) { 469b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_decl_not_lockable) 470b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 471b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 472b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 473b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 474b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4753ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 476b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 4773ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 478b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 479b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 4803ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 4813ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 4823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 4833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 484db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (before) 485768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context, 4863ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 487db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 488768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context, 4893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 490db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 491db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 492db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 493b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 494db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 495db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 496db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 497db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 498b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that the attribute is applied to a function 499b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 500db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 501db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 502db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 503db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 504db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 505b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5063ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 5073ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 508b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 509b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5113ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 5123ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 514db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 515768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(), 5163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5173ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 518db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 519768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(), 5203ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5213ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 522db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 523db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 524db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 525b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 526db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 527db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 528b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 529db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 530db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 531b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 532b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 533db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 534db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 535db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 536db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 537db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 538b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isIntOrBool(Attr.getArg(0))) { 539b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski S.Diag(Attr.getLoc(), diag::err_attribute_first_argument_not_int_or_bool) 540b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski << Attr.getName(); 541b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 542b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski } 543b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5443ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 2> Args; 545b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5463ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1)) 547b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 548b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5493ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5503ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5513ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 552db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 553768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(), 5543ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, 55569f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 5563ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 557db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 558768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(), 55969f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski S.Context, 56069f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski Attr.getArg(0), 56169f5d14bae44f05b22fa50bb87122a61081fcd57Caitlin Sadowski StartArg, Size)); 562db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 563db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 564db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, 565b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski bool exclusive = false) { 566db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 567db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 568b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 569db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 570db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 571b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 572db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 573db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 574db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 575db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 576db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 577b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 5783ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 5793ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 580b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 581b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 5823ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 5833ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 5843ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 5853ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 586db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski if (exclusive) 587768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(), 5883ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5893ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 590db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski else 591768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(), 5923ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski S.Context, StartArg, 5933ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Size)); 594db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 595db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 596db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleUnlockFunAttr(Sema &S, Decl *D, 597b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 598db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 599db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 600db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski // zero or more arguments ok 601db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 602b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 603db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 604db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 605db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 606db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 607db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 608b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6093ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 6103ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true)) 611b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 612b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6133ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6143ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 6153ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6163ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 617768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context, 6183ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 619db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 620db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 621db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLockReturnedAttr(Sema &S, Decl *D, 622b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 623db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 624db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 625b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeNumArgs(S, Attr, 1)) 626db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 6273ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr *Arg = Attr.getArg(0); 628db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 629b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 630db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 631db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 632db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 633db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 634db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6353ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (Arg->isTypeDependent()) 636b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 637b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6383ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski // check that the argument is lockable object 6393ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkForLockableRecord(S, D, Attr, getRecordType(Arg->getType()))) 6403ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski return; 6413ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 642768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context, Arg)); 643db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 644db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 645db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowskistatic void handleLocksExcludedAttr(Sema &S, Decl *D, 646b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski const AttributeList &Attr) { 647db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski assert(!Attr.isInvalid()); 648db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 649b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) 650db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 651db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 652b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) { 653db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 654db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski << Attr.getName() << ExpectedFunctionOrMethod; 655db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski return; 656db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski } 657db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 658b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski // check that all arguments are lockable objects 6593ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski SmallVector<Expr*, 1> Args; 6603ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args)) 661b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski return; 662b51e0315d4ffd12670441ea2284ae1188485df14Caitlin Sadowski 6633ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski unsigned Size = Args.size(); 6643ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski assert(Size == Attr.getNumArgs()); 6653ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski Expr **StartArg = Size == 0 ? 0 : &Args[0]; 6663ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski 667768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context, 6683ac1fbc303d22af2e11a14023ecee7bd7b7d0bfdCaitlin Sadowski StartArg, Size)); 669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski} 670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski 6721b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D, 6731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 67487c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *tDecl = dyn_cast<TypedefNameDecl>(D); 675545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 676803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 677545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 679bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 6819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 6839cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 6849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 6859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 686f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall CXXScopeSpec SS; 687f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall UnqualifiedId id; 688f7a1a744eba4b29ceb0f20af8f34515d892fdd64John McCall id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); 6894ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 6904ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor ExprResult Size = S.ActOnIdExpression(scope, SS, id, false, false); 6914ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor if (Size.isInvalid()) 6924ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor return; 6934ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor 6944ac01401b1ec602a1f58c217544d3dcb5fcbd7f1Douglas Gregor sizeExpr = Size.get(); 6959cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 6969cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 6971731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 6989cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 6991731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 7007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne sizeExpr = Attr.getArg(0); 7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7029cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 7039cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 7049cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 7059ae2f076ca5ab1feb3ba95629099ec2319833701John McCall QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc()); 7069cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 707ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve the old source info. 708a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T)); 709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 7109cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 7119cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 7171731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 719bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 72087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 721768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 72287c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) { 7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 726803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 72808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 730768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context)); 7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 7323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) { 73687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (TagDecl *TD = dyn_cast<TagDecl>(D)) 737768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis TD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context)); 738c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian else 739c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 740c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian} 741c1a0a73c1fad684dd23e9aade02c4e00dbaeaee6Fariborz Jahanian 7421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) { 74396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 7441731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 74596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 74763e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // The IBAction attributes only apply to instance methods. 74887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 74963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek if (MD->isInstanceMethod()) { 750768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context)); 75163e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 75263e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek } 75363e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7544ee2bb12dcb8f8b543a3581537a4bc5752106ce2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName(); 75563e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek} 75663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7572f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenekstatic bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) { 7582f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // The IBOutlet/IBOutletCollection attributes only apply to instance 7592f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // variables or properties of Objective-C classes. The outlet must also 7602f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek // have an object reference type. 7612f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (const ObjCIvarDecl *VD = dyn_cast<ObjCIvarDecl>(D)) { 7622f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!VD->getType()->getAs<ObjCObjectPointerType>()) { 7630bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7642f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << VD->getType() << 0; 7652f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7662f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7672f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7682f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) { 7692f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!PD->getType()->getAs<ObjCObjectPointerType>()) { 7700bfaf067c294bc4064c2f1aee0bc1c51e861ac65Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_iboutlet_object_type) 7712f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek << Attr.getName() << PD->getType() << 1; 7722f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7732f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7742f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7752f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek else { 7762f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_iboutlet) << Attr.getName(); 7772f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return false; 7782f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek } 7792f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 7802f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek return true; 7812f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek} 7822f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 7831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutlet(Sema &S, Decl *D, const AttributeList &Attr) { 78463e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek // check the attribute arguments. 7851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 78663e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 7872f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 7882f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 78963e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek return; 79063e5d7c85299134f088033614afd9eb213c50b48Ted Kremenek 7912f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context)); 79296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 79396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 7941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleIBOutletCollection(Sema &S, Decl *D, 7951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 796857e918a8a40deb128840308a318bf623d68295fTed Kremenek 797857e918a8a40deb128840308a318bf623d68295fTed Kremenek // The iboutletcollection attribute can have zero or one arguments. 798a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (Attr.getParameterName() && Attr.getNumArgs() > 0) { 799857e918a8a40deb128840308a318bf623d68295fTed Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 800857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 801857e918a8a40deb128840308a318bf623d68295fTed Kremenek } 802857e918a8a40deb128840308a318bf623d68295fTed Kremenek 8032f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek if (!checkIBOutletCommon(S, D, Attr)) 804857e918a8a40deb128840308a318bf623d68295fTed Kremenek return; 8052f041d0b12aa87f3345e5fb2e38fefba30c5bff3Ted Kremenek 806a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian IdentifierInfo *II = Attr.getParameterName(); 807a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!II) 808f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian II = &S.Context.Idents.get("NSObject"); 8093a3400b4fdf73887e9d8b4372334bc24a858702fFariborz Jahanian 810b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 81187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.getScopeForContext(D->getDeclContext()->getParent())); 812a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian if (!TypeRep) { 813a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 814a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 815a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 816b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall QualType QT = TypeRep.get(); 817a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // Diagnose use of non-object type in iboutletcollection attribute. 818a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // FIXME. Gnu attribute extension ignores use of builtin types in 819a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // attributes. So, __attribute__((iboutletcollection(char))) will be 820a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian // treated as __attribute__((iboutletcollection())). 821f4072ae44b70a7ac234c47c146157fee75437e38Fariborz Jahanian if (!QT->isObjCIdType() && !QT->isObjCObjectType()) { 822a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II; 823a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian return; 824a8fb24fa3151567056f6125999cea69e39604f35Fariborz Jahanian } 825f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context, 826f1e7af36d6673185994b3d1751cf7e9a9a1491b8Argyrios Kyrtzidis QT, Attr.getParameterLoc())); 827857e918a8a40deb128840308a318bf623d68295fTed Kremenek} 828857e918a8a40deb128840308a318bf623d68295fTed Kremenek 829d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruthstatic void possibleTransparentUnionPointerType(QualType &T) { 83068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (const RecordType *UT = T->getAsUnionType()) 83168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { 83268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian RecordDecl *UD = UT->getDecl(); 83368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian for (RecordDecl::field_iterator it = UD->field_begin(), 83468fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian itend = UD->field_end(); it != itend; ++it) { 83568fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian QualType QT = it->getType(); 83668fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian if (QT->isAnyPointerType() || QT->isBlockPointerType()) { 83768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian T = QT; 83868fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian return; 83968fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 84068fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 84168fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian } 84268fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian} 84368fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 8441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { 845bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 846bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 84787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 848fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 849883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 850eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 851eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 852bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 85307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 85407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 85587c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 85687c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 857eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 858eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 8595f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> NonNullArgs; 860bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 861eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 862eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 863bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 864bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 865eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 8667a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Ex = *I; 867eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 868ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (Ex->isTypeDependent() || Ex->isValueDependent() || 869ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 870fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 872eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 873eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 874bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 875eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 876bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 877eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 878fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 87930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 880eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 881eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 882bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 883465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 88407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 88507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 88607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 88707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_attribute_invalid_implicit_this_argument) 88807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "nonnull" << Ex->getSourceRange(); 88907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 89007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 89107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 89207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 893eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 894eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 89587c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x).getNonReferenceType(); 896d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 89768fe96adf787abd1e98016da0f38e26644faf7b9Fariborz Jahanian 898dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 899eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 900c9ef405559c90fc98b016d00aeae8afbc31c6bf6Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only) 901fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 9027fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 903eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 904bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 905eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 906eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 907bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 908bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 909bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 9107fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 91187c44604325578b8de07d768391c1c9432404f5aChandler Carruth for (unsigned I = 0, E = getFunctionOrMethodNumArgs(D); I != E; ++I) { 91287c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, I).getNonReferenceType(); 913d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth possibleTransparentUnionPointerType(T); 914dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 915d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 91646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 917bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 918ee1c08c88649aaea9dd53272a726cd23de533215Ted Kremenek // No pointer arguments? 91960acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (NonNullArgs.empty()) { 92060acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // Warn the trivial case only if attribute is not coming from a 92160acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian // macro instantiation. 92260acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian if (Attr.getLoc().isFileID()) 92360acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 9247fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 92560acea49c1343e5494edb6da20cac6f9d0b6cfb0Fariborz Jahanian } 926eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 9277fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 9287fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 9297fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 930dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 931768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start, 932cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt size)); 933eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 934eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 9351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { 936dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // This attribute must be applied to a function declaration. 937dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The first argument to the attribute must be a string, 938dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // the name of the resource, for example "malloc". 939dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The following arguments must be argument indexes, the arguments must be 940dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // of integer type for Returns, otherwise of pointer type. 941dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // The difference between Holds and Takes is that a pointer may still be used 9422a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // after being held. free() should be __attribute((ownership_takes)), whereas 9432a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // a list append function may well be __attribute((ownership_holds)). 944dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 945dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!AL.getParameterName()) { 946dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string) 947dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << 1; 948dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 949dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 950dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Figure out our Kind, and check arguments while we're at it. 951cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt OwnershipAttr::OwnershipKind K; 9522a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose switch (AL.getKind()) { 9532a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_takes: 954cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Takes; 955dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 956dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 957dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 958dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9602a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_holds: 961cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Holds; 962dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() < 1) { 963dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 964dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 965dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9662a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9672a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose case AttributeList::AT_ownership_returns: 968cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt K = OwnershipAttr::Returns; 969dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 970dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) 971dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getNumArgs() + 1; 972dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 973dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 9742a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose break; 9752a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 9762a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose // This should never happen given how we are called. 9772a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 978dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 979dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 98087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunction(D) || !hasFunctionProto(D)) { 981883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) 982883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << AL.getName() << ExpectedFunction; 983dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 984dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 985dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 98607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 98707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 98887c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 98987c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 990dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Module = AL.getParameterName()->getName(); 992dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 993dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Normalize the argument, __foo__ becomes foo. 994dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (Module.startswith("__") && Module.endswith("__")) 995dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek Module = Module.substr(2, Module.size() - 4); 996dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<unsigned, 10> OwnershipArgs; 998dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 9992a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E; 10002a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose ++I) { 1001dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 10027a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = *I; 1003dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1004dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1005dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1006dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int) 1007dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << IdxExpr->getSourceRange(); 1008dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1009dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1010dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1011dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 1012dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1013dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (x > NumArgs || x < 1) { 1014dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 1015dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << AL.getName()->getName() << x << IdxExpr->getSourceRange(); 1016dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1017dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1018dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek --x; 101907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 102007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (x == 0) { 102107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(AL.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 102207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "ownership" << IdxExpr->getSourceRange(); 102307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 102407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 102507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth --x; 102607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 102707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 1028dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek switch (K) { 1029cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Takes: 1030cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Holds: { 1031dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument a pointer type? 103287c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = getFunctionOrMethodArgType(D, x); 1033dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 1034dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // FIXME: Should also highlight argument in decl. 1035dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1036cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds") 1037dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "pointer" 1038dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1039dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek continue; 1040dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1041dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1042dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1043cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt case OwnershipAttr::Returns: { 1044dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (AL.getNumArgs() > 1) { 1045dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Is the function argument an integer type? 10467a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = AL.getArg(0); 1047dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::APSInt ArgNum(32); 1048dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() 1049dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) { 1050dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek S.Diag(AL.getLoc(), diag::err_ownership_type) 1051dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << "ownership_returns" << "integer" 1052dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek << IdxExpr->getSourceRange(); 1053dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek return; 1054dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1055dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1056dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek break; 1057dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 10582a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose default: 10592a479929f70d32f626778ef6e70ef46d3a37f74eJordy Rose llvm_unreachable("Unknown ownership attribute"); 1060dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } // switch 1061dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1062dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek // Check we don't have a conflict with another ownership attribute. 1063cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (specific_attr_iterator<OwnershipAttr> 106487c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<OwnershipAttr>(), 106587c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<OwnershipAttr>(); 1066cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) { 1067cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if ((*i)->getOwnKind() != K) { 1068cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end(); 1069cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt I!=E; ++I) { 1070cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (x == *I) { 1071cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) 1072cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt << AL.getName()->getName() << "ownership_*"; 1073dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1074dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1075dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1076dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1077dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek OwnershipArgs.push_back(x); 1078dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1079dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1080dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned* start = OwnershipArgs.data(); 1081dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek unsigned size = OwnershipArgs.size(); 1082dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek llvm::array_pod_sort(start, start + size); 1083cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 1084cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) { 1085cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2; 1086cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 1087dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek } 1088cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 108987c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module, 1090cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt start, size)); 1091dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek} 1092dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek 1093332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// Whether this declaration has internal linkage for the purposes of 1094332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall/// things that want to complain about things not have internal linkage. 1095332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCallstatic bool hasEffectivelyInternalLinkage(NamedDecl *D) { 1096332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall switch (D->getLinkage()) { 1097332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case NoLinkage: 1098332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case InternalLinkage: 1099332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1100332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1101332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // Template instantiations that go from external to unique-external 1102332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // shouldn't get diagnosed. 1103332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case UniqueExternalLinkage: 1104332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return true; 1105332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1106332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall case ExternalLinkage: 1107332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return false; 1108332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1109332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall llvm_unreachable("unknown linkage kind!"); 111011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return false; 111111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 111211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11131b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { 111411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Check the attribute arguments. 111511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() > 1) { 111611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 111711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 111811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 111911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 112087c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 1121332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1122883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1123332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall return; 1124332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall } 1125332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 112687c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1127332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 112811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc rejects 112911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // class c { 113011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 113111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int b() __attribute__((weakref ("f3"))); 113211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // }; 113311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // and ignores the attributes of 113411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // void f(void) { 113511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a __attribute__((weakref ("v2"))); 113611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // } 113711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // we reject them 113887c44604325578b8de07d768391c1c9432404f5aChandler Carruth const DeclContext *Ctx = D->getDeclContext()->getRedeclContext(); 11397a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl if (!Ctx->isFileContext()) { 11407a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) << 1141332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall nd->getNameAsString(); 11427a126a474fdde06382b315b4e3d8ef0a21d4dc31Sebastian Redl return; 114311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 114411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 114511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // The GCC manual says 114611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 114711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // At present, a declaration to which `weakref' is attached can only 114811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // be `static'. 114911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 115011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // It also says 115111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 115211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Without a TARGET, 115311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // given as an argument to `weakref' or to `alias', `weakref' is 115411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // equivalent to `weak'. 115511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // 115611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // gcc 4.4.1 will accept 115711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weakref)); 115811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // as 115911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // int a7 __attribute__((weak)); 116011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // This looks like a bug in gcc. We reject that for now. We should revisit 116111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // it if this behaviour is actually used. 116211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1163332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (!hasEffectivelyInternalLinkage(nd)) { 1164332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_static); 116511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 116611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 116711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 116811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC rejects 116911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static ((alias ("y"), weakref)). 117011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // Should we? How to check that weakref is before or after alias? 117111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 117211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola if (Attr.getNumArgs() == 1) { 11737a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 117411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Arg = Arg->IgnoreParenCasts(); 117511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 117611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11775cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 117811e8ce7380856abee188b237c2600272df2ed09dRafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 117911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola << "weakref" << 1; 118011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 118111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 118211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC will accept anything as the argument of weakref. Should we 118311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // check for an existing decl? 1184768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1185f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 118611e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 118711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 1188768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context)); 118911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola} 119011e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 11911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 11926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1193545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 11943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11987a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12025cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1203fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 12043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1207bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1208bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getTriple().isOSDarwin()) { 1209f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola S.Diag(Attr.getLoc(), diag::err_alias_not_supported_on_darwin); 1210f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola return; 1211f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola } 1212f5fe2925b87cf382f2f13983c81679e38067122bRafael Espindola 12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 1214bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1215768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, 1216f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher Str->getString())); 12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1220dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 12211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1222dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1223dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 122487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1225dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1226883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 1227dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar return; 1228dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar } 1229dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 1230768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context)); 1231dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar} 1232dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar 12331b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlwaysInlineAttr(Sema &S, Decl *D, 12341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1235dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1236831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 12373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1238af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 1239af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 12405bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 124187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 12425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1243883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 12445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 12455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1246bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1247768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context)); 1248af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 1249af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 12501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1251dd0cb22bd62e1e835327f478a2dbf0b8fa439713Daniel Dunbar // Check the attribute arguments. 1252831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 125376168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 125476168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn return; 125576168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn } 12561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 125787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 12581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump QualType RetTy = FD->getResultType(); 12592cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) { 1260768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context)); 12612cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek return; 12622cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek } 1263fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn } 1264fd6ad3cf9c8fc6904bd5f33212207aa69743fd45Ryan Flynn 12652cff7d16fe58e6d6447ec9cad2af083beb20d6b5Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only); 126676168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn} 126776168e289ca4b307259e3bc9b3353f03b05bb6b9Ryan Flynn 12681b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { 126934c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman // check the attribute arguments. 12701731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 127134c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman return; 127234c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 1273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context)); 127434c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman} 127534c26300b384286c544e0b9fd45e7a3648ac79e3Dan Gohman 12761b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 127756aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 127887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1279768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context)); 1280722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1281722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1282883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1283a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1284a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 12851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { 128656aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 128787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isa<VarDecl>(D)) 1288768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context)); 1289722109c1b7718d3e8aab075ce65007b372822199Eric Christopher else 1290722109c1b7718d3e8aab075ce65007b372822199Eric Christopher S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1291883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 1292a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher} 1293a6cf1e709b96865210b81bd611d41e9a2d41500aEric Christopher 12941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { 129587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 1296711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1297711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (S.CheckNoReturnAttr(attr)) return; 1298711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 129987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 1300711c52bb20d0c69063b52a99826fb7d2835501f1John McCall S.Diag(attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1301883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << attr.getName() << ExpectedFunctionOrMethod; 1302711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 1303711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1304711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1305768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context)); 1306711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 1307711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1308711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckNoReturnAttr(const AttributeList &attr) { 1309831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (attr.hasParameterOrArguments()) { 1310711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1311711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 1312711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 1313711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 1314711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 1315711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 1316b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek} 1317b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, 13191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1320b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1321b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // The checking path for 'noreturn' and 'analyzer_noreturn' are different 1322b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek // because 'analyzer_noreturn' does not impact the type. 1323b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 13241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 0)) 13251731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth return; 1326b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 132787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) { 132887c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *VD = dyn_cast<ValueDecl>(D); 13293ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump if (VD == 0 || (!VD->getType()->isBlockPointerType() 13303ee77640c722a70ab7e0181f36dc2af21cab3d23Mike Stump && !VD->getType()->isFunctionPointerType())) { 1331e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara S.Diag(Attr.getLoc(), 1332e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type 1333b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek : diag::warn_attribute_wrong_decl_type) 1334883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1335b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek return; 133619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 13376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1338b56c1cc8ca593f832ca58d682876259c2ed9bec2Ted Kremenek 1339768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context)); 13406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 134235cc9627340b15232139b3c43fcde5973e7fad30John Thompson// PS3 PPU-specific. 13431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) { 134435cc9627340b15232139b3c43fcde5973e7fad30John Thompson/* 134535cc9627340b15232139b3c43fcde5973e7fad30John Thompson Returning a Vector Class in Registers 134635cc9627340b15232139b3c43fcde5973e7fad30John Thompson 1347f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher According to the PPU ABI specifications, a class with a single member of 1348f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher vector type is returned in memory when used as the return value of a function. 1349f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher This results in inefficient code when implementing vector classes. To return 1350f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher the value in a single vector register, add the vecreturn attribute to the 1351f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher class definition. This attribute is also applicable to struct types. 135235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 135335cc9627340b15232139b3c43fcde5973e7fad30John Thompson Example: 135435cc9627340b15232139b3c43fcde5973e7fad30John Thompson 135535cc9627340b15232139b3c43fcde5973e7fad30John Thompson struct Vector 135635cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 135735cc9627340b15232139b3c43fcde5973e7fad30John Thompson __vector float xyzw; 135835cc9627340b15232139b3c43fcde5973e7fad30John Thompson } __attribute__((vecreturn)); 135935cc9627340b15232139b3c43fcde5973e7fad30John Thompson 136035cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector Add(Vector lhs, Vector rhs) 136135cc9627340b15232139b3c43fcde5973e7fad30John Thompson { 136235cc9627340b15232139b3c43fcde5973e7fad30John Thompson Vector result; 136335cc9627340b15232139b3c43fcde5973e7fad30John Thompson result.xyzw = vec_add(lhs.xyzw, rhs.xyzw); 136435cc9627340b15232139b3c43fcde5973e7fad30John Thompson return result; // This will be returned in a register 136535cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 136635cc9627340b15232139b3c43fcde5973e7fad30John Thompson*/ 136787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<RecordDecl>(D)) { 136835cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1369883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedClass; 137035cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 137135cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 137235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 137387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (D->getAttr<VecReturnAttr>()) { 137435cc9627340b15232139b3c43fcde5973e7fad30John Thompson S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn"; 137535cc9627340b15232139b3c43fcde5973e7fad30John Thompson return; 137635cc9627340b15232139b3c43fcde5973e7fad30John Thompson } 137735cc9627340b15232139b3c43fcde5973e7fad30John Thompson 137887c44604325578b8de07d768391c1c9432404f5aChandler Carruth RecordDecl *record = cast<RecordDecl>(D); 137901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson int count = 0; 138001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 138101add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!isa<CXXRecordDecl>(record)) { 138201add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 138301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 138401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 138501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 138601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if (!cast<CXXRecordDecl>(record)->isPOD()) { 138701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record); 138801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 138901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139001add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1391f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher for (RecordDecl::field_iterator iter = record->field_begin(); 1392f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher iter != record->field_end(); iter++) { 139301add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson if ((count == 1) || !iter->getType()->isVectorType()) { 139401add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member); 139501add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson return; 139601add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139701add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson count++; 139801add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson } 139901add59bc8fd178960ad61169bc01566b0d6614cJohn Thompson 1400768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context)); 140135cc9627340b15232139b3c43fcde5973e7fad30John Thompson} 140235cc9627340b15232139b3c43fcde5973e7fad30John Thompson 14031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) { 140487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) && !isa<ParmVarDecl>(D)) { 1405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1406883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrParameter; 1407bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt return; 1408bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 1409bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Actually store the attribute on the declaration 1410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 1411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 14121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 141373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 1414831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 14153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 141673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 141773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1418bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 141987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) && 142087c44604325578b8de07d768391c1c9432404f5aChandler Carruth !isa<TypeDecl>(D) && !isa<LabelDecl>(D)) { 1421fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1422883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableFunctionOrLabel; 142373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 142473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 1425bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1426768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context)); 142773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 142873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 1429f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindolastatic void handleReturnsTwiceAttr(Sema &S, Decl *D, 1430f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola const AttributeList &Attr) { 1431f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola // check the attribute arguments. 1432f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (Attr.hasParameterOrArguments()) { 1433f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1434f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1435f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1436f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1437f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola if (!isa<FunctionDecl>(D)) { 1438f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1439f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola << Attr.getName() << ExpectedFunction; 1440f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola return; 1441f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola } 1442f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 1443f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context)); 1444f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola} 1445f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola 14461b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1447b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 1448831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 1449b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1450b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1451b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1452bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 145387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1454186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 1455b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 1456b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 145887c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (!isFunctionOrMethod(D)) { 1459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1460883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 1461b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 1462b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 1463bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1464768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context)); 1465b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 1466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 14671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1469bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1470bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 14713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1472bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 14733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 14753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 14767a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 14773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1478ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1479ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1480fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 14813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 14823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 14853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1486bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 148787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1488fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1489883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 14903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 14913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 14923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1493768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context, 1494f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 14953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 14963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 14971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) { 14983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 1499bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall if (Attr.getNumArgs() > 1) { 1500bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 15013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 1502bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 15033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 15053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 15067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 15073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 1508ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1509ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1510fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 15113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 15123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 15153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 1516bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 151787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 1518fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1519883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 15203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 15213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 15223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 1523768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context, 1524f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher priority)); 15253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 15263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 15271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeprecatedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1528951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1529951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1530bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1531c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1532c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1533951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1534c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian // Handle the case where deprecated attribute has a text message. 15355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1536951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1537951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1538c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian if (!SE) { 1539951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), diag::err_attribute_not_string) 1540951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner << "deprecated"; 1541c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian return; 1542c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian } 1543951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 15446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1545bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1546768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str)); 15476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 15486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 15491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1550951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner unsigned NumArgs = Attr.getNumArgs(); 1551951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs > 1) { 1552bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1; 1553bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 1554bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 1555951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner 1556c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian // Handle the case where unavailable attribute has a text message. 15575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str; 1558951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner if (NumArgs == 1) { 1559951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(Attr.getArg(0)); 1560c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian if (!SE) { 1561951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner S.Diag(Attr.getArg(0)->getLocStart(), 1562c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian diag::err_attribute_not_string) << "unavailable"; 1563c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian return; 1564c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1565951bbb2a6d9641ea11a6fe81cba429152a055b7cChris Lattner Str = SE->getString(); 1566c784dc1caf0df288a383700f7b57772103b3adabFariborz Jahanian } 1567768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UnavailableAttr(Attr.getRange(), S.Context, Str)); 1568bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 1569bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 1570742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanianstatic void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 1571742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian const AttributeList &Attr) { 1572742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian unsigned NumArgs = Attr.getNumArgs(); 1573742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian if (NumArgs > 0) { 1574742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; 1575742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian return; 1576742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian } 1577742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 1578742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( 1579768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis Attr.getRange(), S.Context)); 1580742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian} 1581742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian 15821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAvailabilityAttr(Sema &S, Decl *D, 15831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 15840a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor IdentifierInfo *Platform = Attr.getParameterName(); 15850a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SourceLocation PlatformLoc = Attr.getParameterLoc(); 15860a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef PlatformName 15880a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor = AvailabilityAttr::getPrettyPlatformName(Platform->getName()); 15890a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (PlatformName.empty()) { 15900a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(PlatformLoc, diag::warn_availability_unknown_platform) 15910a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << Platform; 15920a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15930a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor PlatformName = Platform->getName(); 15940a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 15950a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 15960a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Introduced = Attr.getAvailabilityIntroduced(); 15970a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated(); 15980a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor AvailabilityChange Obsoleted = Attr.getAvailabilityObsoleted(); 1599b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor bool IsUnavailable = Attr.getUnavailableLoc().isValid(); 16000a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1601c90df6a0ad61041e976e0136c29e6d57b17cba3dDouglas Gregor // Ensure that Introduced <= Deprecated <= Obsoleted (although not all 16020a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor // of these steps are needed). 16030a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Deprecated.isValid() && 16043b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Deprecated.Version)) { 16050a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16060a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << PlatformName << Deprecated.Version.getAsString() 16070a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16080a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16090a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16100a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16110a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Introduced.isValid() && Obsoleted.isValid() && 16123b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Introduced.Version <= Obsoleted.Version)) { 16130a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Introduced.KeywordLoc, diag::warn_availability_version_ordering) 16140a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 0 << Introduced.Version.getAsString(); 16160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (Deprecated.isValid() && Obsoleted.isValid() && 16203b6b7accb55980b149571d44e96f92dae500b0a9Douglas Gregor !(Deprecated.Version <= Obsoleted.Version)) { 16210a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Deprecated.KeywordLoc, diag::warn_availability_version_ordering) 16220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 2 << PlatformName << Obsoleted.Version.getAsString() 16230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << 1 << Deprecated.Version.getAsString(); 16240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return; 16250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 16260a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 1627768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AvailabilityAttr(Attr.getRange(), S.Context, 16280a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Platform, 16290a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Introduced.Version, 16300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Deprecated.Version, 1631b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor Obsoleted.Version, 1632b53e417ba487f4193ef3b0485b420e0fdae643a2Douglas Gregor IsUnavailable)); 16330a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor} 16340a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 16351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { 16366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 16371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if(!checkAttributeNumArgs(S, Attr, 1)) 16386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16407a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *Arg = Attr.getArg(0); 16416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 16426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 1643bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16445cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 1645fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 16463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 16476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1649bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef TypeStr = Str->getString(); 1651cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt VisibilityAttr::VisibilityType type; 1652bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1653c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer if (TypeStr == "default") 1654cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Default; 1655c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "hidden") 1656cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; 1657c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "internal") 1658cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Hidden; // FIXME 1659c96f49417b2039d6227b042cd2d975f0869df79dBenjamin Kramer else if (TypeStr == "protected") 1660cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt type = VisibilityAttr::Protected; 16616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 166208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 16636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 16646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1665bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1666768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) VisibilityAttr(Attr.getRange(), S.Context, type)); 16676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 16686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 16691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCMethodFamilyAttr(Sema &S, Decl *decl, 16701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 1671d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl); 1672d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (!method) { 167387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) 1674883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedMethod; 1675d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1676d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1677d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 167887c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 0 || !Attr.getParameterName()) { 167987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!Attr.getParameterName() && Attr.getNumArgs() == 1) { 168087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 1681d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall << "objc_method_family" << 1; 1682d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } else { 168387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1684d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 168587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 1686d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1687d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1688d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 16895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef param = Attr.getParameterName()->getName(); 1690d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall ObjCMethodFamilyAttr::FamilyKind family; 1691d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall if (param == "none") 1692d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_None; 1693d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "alloc") 1694d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_alloc; 1695d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "copy") 1696d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_copy; 1697d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "init") 1698d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_init; 1699d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "mutableCopy") 1700d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_mutableCopy; 1701d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else if (param == "new") 1702d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall family = ObjCMethodFamilyAttr::OMF_new; 1703d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall else { 1704d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // Just warn and ignore it. This is future-proof against new 1705d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall // families being used in system headers. 170687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getParameterLoc(), diag::warn_unknown_method_family); 1707d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall return; 1708d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall } 1709d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 1710f85e193739c953358c865005855253af4f68a497John McCall if (family == ObjCMethodFamilyAttr::OMF_init && 1711f85e193739c953358c865005855253af4f68a497John McCall !method->getResultType()->isObjCObjectPointerType()) { 1712f85e193739c953358c865005855253af4f68a497John McCall S.Diag(method->getLocation(), diag::err_init_method_bad_return_type) 1713f85e193739c953358c865005855253af4f68a497John McCall << method->getResultType(); 1714f85e193739c953358c865005855253af4f68a497John McCall // Ignore the attribute. 1715f85e193739c953358c865005855253af4f68a497John McCall return; 1716f85e193739c953358c865005855253af4f68a497John McCall } 1717f85e193739c953358c865005855253af4f68a497John McCall 1718768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(), 1719f85e193739c953358c865005855253af4f68a497John McCall S.Context, family)); 1720d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall} 1721d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall 17221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCExceptionAttr(Sema &S, Decl *D, 17231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 17241731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 17250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 1726bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 17280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 17290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 17300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 17310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 1732bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1733768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context)); 17340db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 17350db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 17361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) { 1737fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 17382b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1739fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1740fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1741162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 1742fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 1743fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 17446217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 1745fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 1746fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 1747fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1748fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 1749768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context)); 1750fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 1751fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 1752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 17531b03c8719e2e45cf2769430335d7e71f18e6634aChandler CarruthhandleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1754f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 17552b7baf0816a40af3fde3a3e174192a549b785a50John McCall S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1756f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1757f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1758f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1759f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 1760f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 1761f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 1762f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 1763f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 1764768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context)); 1765f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 1766f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 17671b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1768bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1769fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 17703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 17719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1773bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 17753c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 17769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1778bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1779cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt BlocksAttr::BlockType type; 178092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 17819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 17829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 1783fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 17843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 17859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 17869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 1787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1788768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type)); 17899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 17909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 17911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) { 1792770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 1793770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 1794bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 1795770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1796bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1797bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17983323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned sentinel = 0; 1799770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 18007a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(0); 1801770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1802ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1803ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1804fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 1806770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1807770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1808bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18093323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if (Idx.isSigned() && Idx.isNegative()) { 1810fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 1811fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1812770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1813770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 18143323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall 18153323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall sentinel = Idx.getZExtValue(); 1816770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1817770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 18183323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall unsigned nullPos = 0; 1819770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 18207a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(1); 1821770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 1822ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1823ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(Idx, S.Context)) { 1824fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 18253c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 1826770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1827770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1828770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 1829bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18303323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall if ((Idx.isSigned() && Idx.isNegative()) || nullPos > 1) { 1831770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 1832770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 1833fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 1834fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 1835770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1836770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1837770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1838770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 183987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 18403323fad09e9f2c280e0dbe767be398203bb0c6acJohn McCall const FunctionType *FT = FD->getType()->castAs<FunctionType>(); 1841897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 1842897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 1843897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 1844897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 1845bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1846897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 18473bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1848770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1849bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 185087c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 1851770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 18523bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 1853770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 18542f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 185587c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (isa<BlockDecl>(D)) { 1856bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 1857bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 18582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 185987c44604325578b8de07d768391c1c9432404f5aChandler Carruth } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { 18602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 1861daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 186287c44604325578b8de07d768391c1c9432404f5aChandler Carruth const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D) 1863f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>(); 18642f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 18653bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 18663bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 18672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 18682f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1869ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else { 18702f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1871883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 18722f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 18732f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 1874770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 1875fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1876883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionMethodOrBlock; 1877770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 1878770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 1879768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel, 1880f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher nullPos)); 1881770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 1882770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 18831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) { 1884026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 18851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 1886026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1887026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 1888f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (!isFunction(D) && !isa<ObjCMethodDecl>(D)) { 1889026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1890883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 1891026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 1892026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 1893bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1894f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) { 1895f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1896f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 0; 1897f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes return; 1898f857798fa77ac50c6d0a262d96ad6176187190e3Nuno Lopes } 1899f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 1900f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian if (MD->getResultType()->isVoidType()) { 1901f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method) 1902f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian << Attr.getName() << 1; 1903f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian return; 1904f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian } 1905f031774aa2638b4d3f487e7e44180c1f89b867efFariborz Jahanian 1906768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context)); 1907026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 1908026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 19091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 191187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.hasParameterOrArguments()) { 191287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 19136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 19146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 19156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 191687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) { 191713c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian if (isa<CXXRecordDecl>(D)) { 191813c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 191913c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian return; 192013c7fcceb9fd96f5be03af038ce16b05bb5e9598Fariborz Jahanian } 192187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 192287c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedVariableOrFunction; 1923f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 1924f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 1925f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 192687c44604325578b8de07d768391c1c9432404f5aChandler Carruth NamedDecl *nd = cast<NamedDecl>(D); 1927332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall 1928332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall // 'weak' only applies to declarations with external linkage. 1929332bb2a2e3cd0a5af85758847a8050ae8ceee5f3John McCall if (hasEffectivelyInternalLinkage(nd)) { 193087c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_weak_static); 19316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 1933bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1934768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context)); 19356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 19366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 19371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) { 19386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 19391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 19406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19411731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 19426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 19446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 19450a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (!D->canBeWeakImported(isDef)) { 19460a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isDef) 19470a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor S.Diag(Attr.getLoc(), 19480a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor diag::warn_attribute_weak_import_invalid_on_definition) 19490a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor << "weak_import" << 2 /*variable and function*/; 1950def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) || 1951bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (S.Context.getTargetInfo().getTriple().isOSDarwin() && 195290eed219f4215adf300800ab7478f568c7a4b2a3Fariborz Jahanian (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) { 1953def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor // Nothing to warn about here. 1954def863192f83d8033e1833b48ae8119a65dfc7c8Douglas Gregor } else 1955c034974f103873bdccc91da99a30ab30295b5226Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1956883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 19576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19586e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 19596e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 19606e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 1961768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context)); 19626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 19636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 19641b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleReqdWorkGroupSize(Sema &S, Decl *D, 19651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 19666f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 19671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 3)) 19686f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 19696f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 19706f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 19716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 19727a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *E = Attr.getArg(i); 19736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 1974ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (E->isTypeDependent() || E->isValueDependent() || 1975ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !E->isIntegerConstantExpr(ArgNum, S.Context)) { 19766f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 19776f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 19786f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 19796f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 19806f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 19816f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 1982768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context, 1983cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt WGSize[0], WGSize[1], 19846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 19856f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 19866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 19871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) { 198817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 19891731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 199017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 199117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 199217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 199317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 19947a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 1995797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 199617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 1997797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) << "section"; 199817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 199917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 20001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2001797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner // If the target wants to validate the section specifier, make it happen. 2002bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor std::string Error = S.Context.getTargetInfo().isValidSectionSpecifier(SE->getString()); 2003a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (!Error.empty()) { 2004a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_invalid_for_target) 2005a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner << Error; 2006797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner return; 2007797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner } 20081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2009a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner // This attribute cannot be applied to local variables. 2010a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) { 2011a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable); 2012a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner return; 2013a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner } 2014a1e1dc77e995b746826b64752751dbf35f323767Chris Lattner 2015768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) SectionAttr(Attr.getRange(), S.Context, 2016f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 201717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 201817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 20196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) { 20216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2022831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 20233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 20246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 20256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2026b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 202787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) { 2028b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2029ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2030b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2031768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context)); 2032b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 20336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 20346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 20351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2036232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 2037831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 20383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2039232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2040232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 2041bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 204287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ConstAttr *Existing = D->getAttr<ConstAttr>()) { 2043b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (Existing->getLocation().isInvalid()) 2044ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis Existing->setRange(Attr.getRange()); 2045b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } else { 2046768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context)); 2047b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2048232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2049232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 20501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2051232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 20521731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2053232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 2054bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2055768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context)); 2056232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 2057232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 20581b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2059bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 2060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2063bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2064f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 2065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2066f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2067f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2068bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 206987c44604325578b8de07d768391c1c9432404f5aChandler Carruth VarDecl *VD = dyn_cast<VarDecl>(D); 2070bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2071f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 2072f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 2073f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2074f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2075bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2076f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 2077c83c6874e3bf1432d3df5e8d3530f8561ff5441fDouglas Gregor // FIXME: Lookup probably isn't looking in the right place 2078f36e02d4aff98bf2e52e342e0038d4172fbb5e64John McCall NamedDecl *CleanupDecl 2079f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis = S.LookupSingleName(S.TUScope, Attr.getParameterName(), 2080f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis Attr.getParameterLoc(), Sema::LookupOrdinaryName); 2081f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 2082f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), diag::err_attribute_cleanup_arg_not_found) << 2083f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 2084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2086bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2087f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 2088f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 2089f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2090f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_arg_not_function) 2091f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2092f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2093f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2094f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2095f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 2096f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 2097f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis diag::err_attribute_cleanup_func_must_take_one_arg) 2098f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis << Attr.getParameterName(); 2099f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 2100f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 2101bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 210289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 210389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 210489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 210589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 2106b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(), 2107b608b987718c6d841115464f79ab2d1820a63e17Douglas Gregor ParamTy, Ty) != Sema::Compatible) { 2108f0b0ccce127857e7e4fb829e017dbcb7487884c4Argyrios Kyrtzidis S.Diag(Attr.getParameterLoc(), 210989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 211089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 211189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 211289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 2113bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2114768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD)); 2115223ae5c26654e5fd7dacdafe43aff28a096ba63bArgyrios Kyrtzidis S.MarkDeclarationReferenced(Attr.getParameterLoc(), FD); 2116f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 2117f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 2118bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 2119bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 21201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) { 21211731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 21225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21231731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 212487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) { 21255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2126883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 21275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 212907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 213007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 213107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 213287c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 213387c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 21345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 213507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 21365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 21377a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 21385b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 2139ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2140ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 21415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 21425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 21435b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2145bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 21475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 21485b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 21495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 21505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 2151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 2153bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 215407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (HasImplicitThisParam) { 215507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth if (ArgIdx == 0) { 215607d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_invalid_implicit_this_argument) 215707d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << "format_arg" << IdxExpr->getSourceRange(); 215807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth return; 215907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 216007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth ArgIdx--; 216107d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth } 216207d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth 21635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 216487c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 2165bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 21665b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 21675b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 21685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 21695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 21706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 21715b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 21725b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2173bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 21745b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 21755b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2176bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 217787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Ty = getFunctionOrMethodResultType(D); 21785b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 21795b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 21805b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 21816217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 21825b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 21835b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 2184bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 21855b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 21865b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 2187bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 2188bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2189768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context, 219007d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth Idx.getZExtValue())); 21915b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 21925b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 21932b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbarenum FormatAttrKind { 21942b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar CFStringFormat, 21952b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar NSStringFormat, 21962b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar StrftimeFormat, 21972b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar SupportedFormat, 21983c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner IgnoredFormat, 21992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar InvalidFormat 22002b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar}; 22012b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22022b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// getFormatAttrKind - Map from format attribute names to supported format 22032b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar/// types. 22045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic FormatAttrKind getFormatAttrKind(StringRef Format) { 22052b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for formats that get handled specially. 22062b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "NSString") 22072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return NSStringFormat; 22082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "CFString") 22092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return CFStringFormat; 22102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "strftime") 22112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return StrftimeFormat; 22122b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 22132b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Otherwise, check for supported formats. 22142b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format == "scanf" || Format == "printf" || Format == "printf0" || 22152b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "strfmon" || Format == "cmn_err" || Format == "strftime" || 22162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format == "NSString" || Format == "CFString" || Format == "vcmn_err" || 2217cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "zcmn_err" || 2218cd5b306f1b79c8a82fb0bdb4cf353021ea452fedChris Lattner Format == "kprintf") // OpenBSD. 22192b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return SupportedFormat; 22202b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2221bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands if (Format == "gcc_diag" || Format == "gcc_cdiag" || 2222bc52595e01323ca22d65c68aafd53a1acb8c1fb6Duncan Sands Format == "gcc_cxxdiag" || Format == "gcc_tdiag") 22233c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return IgnoredFormat; 22243c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 22252b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar return InvalidFormat; 22262b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar} 22272b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 2228521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// Handle __attribute__((init_priority(priority))) attributes based on 2229521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html 22301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleInitPriorityAttr(Sema &S, Decl *D, 22311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 2232521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (!S.getLangOptions().CPlusPlus) { 2233521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2234521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2235521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2236521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 223787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) { 2238b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2239b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2240b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2241b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 224287c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType T = dyn_cast<VarDecl>(D)->getType(); 2243b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (S.Context.getAsArrayType(T)) 2244b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian T = S.Context.getBaseElementType(T); 2245b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian if (!T->getAs<RecordType>()) { 2246b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr); 2247b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian Attr.setInvalid(); 2248b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian return; 2249b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian } 2250b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2251521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (Attr.getNumArgs() != 1) { 2252521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 2253521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2254521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2255521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 22567a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *priorityExpr = Attr.getArg(0); 2257b9d5c22529c3f2bf3b03348021c0fd1c723d8516Fariborz Jahanian 2258521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian llvm::APSInt priority(32); 2259521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() || 2260521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian !priorityExpr->isIntegerConstantExpr(priority, S.Context)) { 2261521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 2262521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << "init_priority" << priorityExpr->getSourceRange(); 2263521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2264521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2265521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 22669f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned prioritynum = priority.getZExtValue(); 2267521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian if (prioritynum < 101 || prioritynum > 65535) { 2268521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range) 2269521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian << priorityExpr->getSourceRange(); 2270521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian Attr.setInvalid(); 2271521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian return; 2272521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian } 2273768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context, 2274f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher prioritynum)); 2275521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian} 2276521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 2277bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 2278bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 22791b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleFormatAttr(Sema &S, Decl *D, const AttributeList &Attr) { 22806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2281545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 2282fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 22833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 22846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2287545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 22883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 22896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 229287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) { 2293fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2294883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 22956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 22966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 22976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 229807d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // In C++ the implicit 'this' function parameter also counts, and they are 229907d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth // counted from one. 230087c44604325578b8de07d768391c1c9432404f5aChandler Carruth bool HasImplicitThisParam = isInstanceMethod(D); 230187c44604325578b8de07d768391c1c9432404f5aChandler Carruth unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam; 23026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 23036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23045f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Format = Attr.getParameterName()->getName(); 23056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 23072b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Format.startswith("__") && Format.endswith("__")) 23082b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar Format = Format.substr(2, Format.size() - 4); 23092b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar 23102b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar // Check for supported formats. 23112b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FormatAttrKind Kind = getFormatAttrKind(Format); 23123c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23133c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner if (Kind == IgnoredFormat) 23143c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner return; 23153c989027f68e2d9dfd57c018ccc550bd9fb79920Chris Lattner 23162b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == InvalidFormat) { 2317fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 231801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar << "format" << Attr.getParameterName()->getName(); 23196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 23237a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *IdxExpr = Attr.getArg(0); 2324803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 2325ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() || 2326ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 2327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 2333fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 23343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 23356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 23396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 2340bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 23414a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (HasImplicitThisParam) { 23424a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (ArgIdx == 0) { 234307d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth S.Diag(Attr.getLoc(), 234407d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth diag::err_format_attribute_implicit_this_format_string) 234507d7e7a6b10f798459f350b792713db2fb3e9365Chandler Carruth << IdxExpr->getSourceRange(); 23464a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 23474a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 23484a2614e94672c47395abcde60518776fbebec589Sebastian Redl ArgIdx--; 23494a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 23501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 235287c44604325578b8de07d768391c1c9432404f5aChandler Carruth QualType Ty = getFunctionOrMethodArgType(D, ArgIdx); 23536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23542b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == CFStringFormat) { 2355085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 2356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 2358085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 2359085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 23602b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar } else if (Kind == NSStringFormat) { 2361390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 2362390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 2363803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 2364390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2365fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2366fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 23676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2368bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 23696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 23706217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 2371390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 2372fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 2373fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 23746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 23787a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *FirstArgExpr = Attr.getArg(1); 2379803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 2380ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() || 2381ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 2382fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 23833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 23846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 23886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 238987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (isFunctionOrMethodVariadic(D)) { 23906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 23916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 239287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic); 23936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 23946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 23966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 23983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 23992b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar if (Kind == StrftimeFormat) { 24006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 2401fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 2402fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 24036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 24066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 2407fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 24083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 24096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2412b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // Check whether we already have an equivalent format attribute. 2413b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor for (specific_attr_iterator<FormatAttr> 241487c44604325578b8de07d768391c1c9432404f5aChandler Carruth i = D->specific_attr_begin<FormatAttr>(), 241587c44604325578b8de07d768391c1c9432404f5aChandler Carruth e = D->specific_attr_end<FormatAttr>(); 2416b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor i != e ; ++i) { 2417b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor FormatAttr *f = *i; 2418b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getType() == Format && 2419b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFormatIdx() == (int)Idx.getZExtValue() && 2420b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor f->getFirstArg() == (int)FirstArg.getZExtValue()) { 2421b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // If we don't have a valid location for this attribute, adopt the 2422b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor // location. 2423b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor if (f->getLocation().isInvalid()) 2424ffcc3105d223899740e79f3f8199f3881df4d1deArgyrios Kyrtzidis f->setRange(Attr.getRange()); 2425b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor return; 2426b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2427b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor } 2428b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4Douglas Gregor 2429768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FormatAttr(Attr.getRange(), S.Context, Format, 2430cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt Idx.getZExtValue(), 24312b0d9a247ab375ca316bf04feede73de6672fc31Daniel Dunbar FirstArg.getZExtValue())); 24326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 24336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleTransparentUnionAttr(Sema &S, Decl *D, 24351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 24366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 24371731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 24386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24391731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 24406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 24420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 244387c44604325578b8de07d768391c1c9432404f5aChandler Carruth TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D); 24440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 24450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 24460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 244787c44604325578b8de07d768391c1c9432404f5aChandler Carruth RD = dyn_cast<RecordDecl>(D); 24480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 24490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 2450fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2451883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedUnion; 24526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 24536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24555e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall if (!RD->isCompleteDefinition()) { 2456bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 24570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 24580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 24600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 246117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 246217945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 24630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 24640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 24650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2467bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 24680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 24690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 247090cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) { 2471bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 247290cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor diag::warn_transparent_union_attribute_floating) 247390cd672ed107d5986936c577ce47ad7374096bd2Douglas Gregor << FirstType->isVectorType() << FirstType; 24740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 24750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 2476bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 24770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 24780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 24790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 24800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 24810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 24820c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 24830c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 24840c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 2485bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 24860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 2487bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 24880c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 24890c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 24900c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 2491bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 24920c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 24930c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 2494bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 2495bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 2496bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 24976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2498768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context)); 24996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) { 25026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 25031731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 25046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25051731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 25067a73002783b30dcf613b06dbe618cfc1d1116ff8Peter Collingbourne Expr *ArgExpr = Attr.getArg(0); 2507797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(ArgExpr); 2508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 25096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 25106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 25116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 2512797c3c4f5dc4fda735e55c6b5d6270a54cf6d263Chris Lattner S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; 25136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 251577f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge 251677f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge // Don't duplicate annotations that are already set. 251777f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge for (specific_attr_iterator<AnnotateAttr> 251877f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge i = D->specific_attr_begin<AnnotateAttr>(), 251977f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) { 252077f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge if ((*i)->getAnnotation() == SE->getString()) 252177f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge return; 252277f68bb90af93b95045fb994e7cd68137adcc132Julien Lerouge } 2523768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context, 2524f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher SE->getString())); 25256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 25266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 25271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 25286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 2529545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 25303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 25316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2533bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2534bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt //FIXME: The C++0x version of this attribute has more limited applicabilty 2535bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // than GNU's, and should error out when it is used to specify a 2536bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // weaker alignment, rather than being silently ignored. 25376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2538545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 2539768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); 25404ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth return; 25414ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth } 25424ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2543768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); 25444ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth} 25454ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth 2546768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { 25470b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne // FIXME: Handle pack-expansions here. 25480b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne if (DiagnoseUnexpandedParameterPack(E)) 25490b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne return; 25500b64ba926752110cff1344a46b36e29396cc4d25Peter Collingbourne 25514ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (E->isTypeDependent() || E->isValueDependent()) { 25524ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth // Save dependent expressions in the AST to be instantiated. 2553768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 25546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 25556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2556bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2557768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis SourceLocation AttrLoc = AttrRange.getBegin(); 2558cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object? 255949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 25604ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth if (!E->isIntegerConstantExpr(Alignment, Context)) { 25614ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_argument_not_int) 25624ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << "aligned" << E->getSourceRange(); 256349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 256449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 2565396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 25664ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) 25674ced79f0971592e6e7122037de69ee9ae534ce72Chandler Carruth << E->getSourceRange(); 2568396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 2569396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 2570396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 2571768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); 2572cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt} 2573cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt 2574768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidisvoid Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { 2575cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Cache the number on the Attr object if non-dependent? 2576cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt // FIXME: Perform checking of type validity 2577768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); 2578cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt return; 25796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2580fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2581d309c8195cd89fef9ed13507f7ee9ac70561cebbChandler Carruth/// handleModeAttr - This attribute modifies the width of a decl with primitive 2582bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 2583fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 2584bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 2585bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 2586bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 25871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleModeAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2588fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 2589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 2590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 25921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2593fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 25941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2595fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2596fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 2597fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 25980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 2599fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2600fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2601210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar 26025f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = Attr.getParameterName()->getName(); 2603fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2604fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 2605210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str.startswith("__") && Str.endswith("__")) 2606210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar Str = Str.substr(2, Str.size() - 4); 2607fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2608fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 2609fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 261073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 2611210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar switch (Str.size()) { 2612fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 261373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 261473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 261573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 261673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 261773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 261873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 261973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 262073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 262173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 262273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 262373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 262473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 262573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 262673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 262773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 262873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2629fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2630fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 2631fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 2632fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 2633210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "word") 2634bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2635210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar else if (Str == "byte") 2636bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getCharWidth(); 2637fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2638fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 2639210ae989a51dcb115b928829abd7c4c4ae0c01bdDaniel Dunbar if (Str == "pointer") 2640bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor DestWidth = S.Context.getTargetInfo().getPointerWidth(0); 2641fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2642fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2643fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2644fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 2645162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) 2646fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 2647fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 2648fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 2649fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 2650fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 2651768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << "mode" << Attr.getRange(); 2652fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2653fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 265473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2655183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall if (!OldTy->getAs<BuiltinType>() && !OldTy->isComplexType()) 265673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 265773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 26582ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!OldTy->isIntegralOrEnumerationType()) 265973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 266073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 266173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 266273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 266373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 266473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 266573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 266673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 266773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 2668390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 2669390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 2670390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 2671390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 2672f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 2673f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 2674fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 2675fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 2676fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 26773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 2678fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2679fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 26803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2681fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 2682fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 268373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 268473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 268573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 268673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2687fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 26880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 2689fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 26900b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 2691fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2692fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 269373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 269473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 269573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 269673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 2697fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 26980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 2699fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 2701fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2702fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 2703fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 2705fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 27060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 2707fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 27080b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 2709fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 2710fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 2711fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 27120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 2713fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 2714bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2715aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongTy; 2716aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2717aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.LongLongTy; 2718fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 2719bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (S.Context.getTargetInfo().getLongWidth() == 64) 2720aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongTy; 2721aec7caa3c40891727164167ece11d552422803d2Chandler Carruth else 2722aec7caa3c40891727164167ece11d552422803d2Chandler Carruth NewTy = S.Context.UnsignedLongLongTy; 2723fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 272473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 272573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 272673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2727f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 2728f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 2729f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 2730f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 2731f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 2732f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson if (OldTy->isSignedIntegerType()) 2733f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.Int128Ty; 2734f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson else 2735f5f7d864f5067d1ea4bff7fcf41b53a43b7b48baAnders Carlsson NewTy = S.Context.UnsignedInt128Ty; 273673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 2737fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2738fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 273973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 274073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 2741fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 2742fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 2743fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 2744162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { 2745ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall // FIXME: preserve existing source info. 2746a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TD->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(NewTy)); 2747ba6a9bd384df475780be636ca45bcef5c5bbd19fJohn McCall } else 2748fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 2749fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 27500744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 27511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoDebugAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2752d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 27531731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2754d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2755e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 275687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 2757d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2758883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2759d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 2760d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 2761bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2762768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context)); 2763d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 2764d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 27651b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 27665bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 27671731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 27685bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 27691731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2770bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 277187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 27725bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2773883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 27745bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 27755bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 2776bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2777768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context)); 27785bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 27795bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 27801b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNoInstrumentFunctionAttr(Sema &S, Decl *D, 27811b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 27827255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner // check the attribute arguments. 27831731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 27847255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 27851731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 27867255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 278787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 27887255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2789883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 27907255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner return; 27917255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner } 27927255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 2793768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(), 2794f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 27957255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner} 27967255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner 27971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2798ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2799ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2800831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if (Attr.hasParameterOrArguments()) { 2801ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2802ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2803ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2804ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 280587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2806ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2807883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2808ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2809ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2810ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2811768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context)); 2812ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2813ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant"; 2814ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2815ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2816ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2818ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2819ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 2820ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (Attr.getNumArgs() != 0) { 2821ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2822ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2823ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2824ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 282587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 2826ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2827883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariableOrFunction; 2828ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2829ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2830ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2831768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context)); 2832ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2833ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device"; 2834ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2835ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2836ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2838ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2839ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28401731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2841ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2842ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 284387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2844ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2845883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2846ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2847ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2848ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 284987c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *FD = cast<FunctionDecl>(D); 28502c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (!FD->getResultType()->isVoidType()) { 2851723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); 28522c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne if (FunctionTypeLoc* FTL = dyn_cast<FunctionTypeLoc>(&TL)) { 28532c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 28542c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType() 28552c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FixItHint::CreateReplacement(FTL->getResultLoc().getSourceRange(), 28562c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne "void"); 28572c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } else { 28582c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return) 28592c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne << FD->getType(); 28602c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 28612c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne return; 28622c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne } 28632c2c8dd0acb2a51067299bfcec9ff2145f2031c8Peter Collingbourne 2864768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context)); 2865ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2866ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global"; 2867ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2868ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2869ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2871ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2872ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28731731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2874ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 28751731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2876ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 287787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<FunctionDecl>(D)) { 2878ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2879883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 2880ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2881ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2882ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2883768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context)); 2884ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2885ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host"; 2886ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2887ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2888ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 28891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 2890ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne if (S.LangOpts.CUDA) { 2891ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne // check the attribute arguments. 28921731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 2893ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 28941731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 2895ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 289687c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D)) { 2897ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2898883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedVariable; 2899ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne return; 2900ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2901ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 2902768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context)); 2903ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } else { 2904ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared"; 2905ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne } 2906ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne} 2907ced7671c18e115ac3c3f54abfaaafcc6d33edc4cPeter Collingbourne 29081b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { 290926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 29101731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 0)) 291126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 2912bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 291387c44604325578b8de07d768391c1c9432404f5aChandler Carruth FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 2914c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 291526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 2916883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunction; 291726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 291826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 2919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 29200130f3cc4ccd5f46361c48d5fe94133d74619424Douglas Gregor if (!Fn->isInlineSpecified()) { 2921cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 2922c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 2923c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 2924bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2925768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context)); 292626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 292726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 29281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) { 292987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 2930711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 293187c44604325578b8de07d768391c1c9432404f5aChandler Carruth // Diagnostic is emitted elsewhere: here we store the (valid) Attr 2932e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara // in the Decl node for syntactic reasoning, e.g., pretty-printing. 2933711c52bb20d0c69063b52a99826fb7d2835501f1John McCall CallingConv CC; 293487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckCallingConvAttr(Attr, CC)) 2935711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2936e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 293787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 293887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 293987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 2940711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 2941711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 2942711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 294387c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 2944e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_fastcall: 2945768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context)); 2946e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2947e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_stdcall: 2948768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context)); 2949e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2950f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 2951768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context)); 295204633eb86621747bece5643f5909222e2dd6884fDouglas Gregor return; 2953e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara case AttributeList::AT_cdecl: 2954768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context)); 2955e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 295652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 2957768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context)); 295852fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik return; 2959414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 296087c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *Arg = Attr.getArg(0); 2961414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 29625cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 296387c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 2964414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 296587c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2966414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 2967414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2968414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 29695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 2970414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PcsAttr::PCSType PCS; 2971414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") 2972414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS; 2973414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else if (StrRef == "aapcs-vfp") 2974414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov PCS = PcsAttr::AAPCS_VFP; 2975414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov else { 297687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_invalid_pcs); 297787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 2978414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return; 2979414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2980414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 2981768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS)); 2982414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 2983e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara default: 2984e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara llvm_unreachable("unexpected attribute kind"); 2985e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara return; 2986e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara } 2987e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara} 2988e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 29891b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){ 299056aeb40b1ca136cfd68fdbaf87f971eaf1c7a4afChandler Carruth assert(!Attr.isInvalid()); 2991768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context)); 2992f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne} 2993f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne 2994711c52bb20d0c69063b52a99826fb7d2835501f1John McCallbool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC) { 2995711c52bb20d0c69063b52a99826fb7d2835501f1John McCall if (attr.isInvalid()) 2996711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 2997711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 2998831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek if ((attr.getNumArgs() != 0 && 2999831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek !(attr.getKind() == AttributeList::AT_pcs && attr.getNumArgs() == 1)) || 3000831efaeb4ba2c0939db6eeb77229d9e47dd03c9cTed Kremenek attr.getParameterName()) { 3001711c52bb20d0c69063b52a99826fb7d2835501f1John McCall Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 3002711c52bb20d0c69063b52a99826fb7d2835501f1John McCall attr.setInvalid(); 3003711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3004ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 300555d3aaf9a537888734762170823daf750ea9036dEli Friedman 3006414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // TODO: diagnose uses of these conventions on the wrong target. Or, better 3007414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // move to TargetAttributesSema one day. 3008711c52bb20d0c69063b52a99826fb7d2835501f1John McCall switch (attr.getKind()) { 3009711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_cdecl: CC = CC_C; break; 3010711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_fastcall: CC = CC_X86FastCall; break; 3011711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_stdcall: CC = CC_X86StdCall; break; 3012711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break; 3013711c52bb20d0c69063b52a99826fb7d2835501f1John McCall case AttributeList::AT_pascal: CC = CC_X86Pascal; break; 3014414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: { 3015414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Expr *Arg = attr.getArg(0); 3016414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 30175cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3018414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov Diag(attr.getLoc(), diag::err_attribute_argument_n_not_string) 3019414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov << "pcs" << 1; 3020414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov attr.setInvalid(); 3021414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov return true; 3022414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3023414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov 30245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3025414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov if (StrRef == "aapcs") { 3026414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS; 3027414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3028414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } else if (StrRef == "aapcs-vfp") { 3029414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov CC = CC_AAPCS_VFP; 3030414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov break; 3031414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3032414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov // FALLS THROUGH 3033414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov } 3034711c52bb20d0c69063b52a99826fb7d2835501f1John McCall default: llvm_unreachable("unexpected attribute kind"); return true; 3035711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3036711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3037711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3038711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3039711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 30401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) { 304187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3042711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3043711c52bb20d0c69063b52a99826fb7d2835501f1John McCall unsigned numParams; 304487c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (S.CheckRegparmAttr(Attr, numParams)) 3045711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return; 3046711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 304787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 304887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 304987c44604325578b8de07d768391c1c9432404f5aChandler Carruth << Attr.getName() << ExpectedFunctionOrMethod; 3050ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 3051ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 305255d3aaf9a537888734762170823daf750ea9036dEli Friedman 3053768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams)); 3054711c52bb20d0c69063b52a99826fb7d2835501f1John McCall} 3055711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 3056711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// Checks a regparm attribute, returning true if it is ill-formed and 3057711c52bb20d0c69063b52a99826fb7d2835501f1John McCall/// otherwise setting numParams to the appropriate value. 305887c44604325578b8de07d768391c1c9432404f5aChandler Carruthbool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) { 305987c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.isInvalid()) 3060711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3061711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 306287c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getNumArgs() != 1) { 306387c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 306487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3065711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 3066711c52bb20d0c69063b52a99826fb7d2835501f1John McCall } 3067711c52bb20d0c69063b52a99826fb7d2835501f1John McCall 306887c44604325578b8de07d768391c1c9432404f5aChandler Carruth Expr *NumParamsExpr = Attr.getArg(0); 306955d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 3070ac06a0e1e3feb95c2ffd352c086882b492a65b99Douglas Gregor if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() || 3071711c52bb20d0c69063b52a99826fb7d2835501f1John McCall !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) { 307287c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 307355d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 307487c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3075711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 307655d3aaf9a537888734762170823daf750ea9036dEli Friedman } 307755d3aaf9a537888734762170823daf750ea9036dEli Friedman 3078bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (Context.getTargetInfo().getRegParmMax() == 0) { 307987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 308055d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 308187c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3082711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 308355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 308455d3aaf9a537888734762170823daf750ea9036dEli Friedman 3085711c52bb20d0c69063b52a99826fb7d2835501f1John McCall numParams = NumParams.getZExtValue(); 3086bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (numParams > Context.getTargetInfo().getRegParmMax()) { 308787c44604325578b8de07d768391c1c9432404f5aChandler Carruth Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 3088bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange(); 308987c44604325578b8de07d768391c1c9432404f5aChandler Carruth Attr.setInvalid(); 3090711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return true; 309155d3aaf9a537888734762170823daf750ea9036dEli Friedman } 309255d3aaf9a537888734762170823daf750ea9036dEli Friedman 3093711c52bb20d0c69063b52a99826fb7d2835501f1John McCall return false; 3094ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 3095ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 30961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){ 30977b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (S.LangOpts.CUDA) { 30987b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne // check the attribute arguments. 30997b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) { 3100bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall // FIXME: 0 is not okay. 3101bdc49d360f98c1194d50b8bbb24885bf8d4c1ac4John McCall S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2; 31027b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31037b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31047b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 310587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isFunctionOrMethod(D)) { 31067b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3107883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << Attr.getName() << ExpectedFunctionOrMethod; 31087b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31097b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31107b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31117b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MaxThreadsExpr = Attr.getArg(0); 31127b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MaxThreads(32); 31137b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MaxThreadsExpr->isTypeDependent() || 31147b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreadsExpr->isValueDependent() || 31157b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) { 31167b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 31177b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 1 << MaxThreadsExpr->getSourceRange(); 31187b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31197b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31207b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31217b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne llvm::APSInt MinBlocks(32); 31227b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (Attr.getNumArgs() > 1) { 31237b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne Expr *MinBlocksExpr = Attr.getArg(1); 31247b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne if (MinBlocksExpr->isTypeDependent() || 31257b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocksExpr->isValueDependent() || 31267b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) { 31277b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 31287b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne << "launch_bounds" << 2 << MinBlocksExpr->getSourceRange(); 31297b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne return; 31307b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31317b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31327b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 3133768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context, 31347b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MaxThreads.getZExtValue(), 31357b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne MinBlocks.getZExtValue())); 31367b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } else { 31377b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds"; 31387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne } 31397b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne} 31407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne 31410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 3142b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 3143b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 3144b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3145c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfNSAttribute(Sema &S, QualType type) { 31466c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 31476c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isObjCObjectPointerType() || 31486c73a2975ba9112787380abd878876336957b3f6Douglas Gregor S.Context.isObjCNSObjectType(type); 3149c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3150c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCallstatic bool isValidSubjectOfCFAttribute(Sema &S, QualType type) { 31516c73a2975ba9112787380abd878876336957b3f6Douglas Gregor return type->isDependentType() || 31526c73a2975ba9112787380abd878876336957b3f6Douglas Gregor type->isPointerType() || 31536c73a2975ba9112787380abd878876336957b3f6Douglas Gregor isValidSubjectOfNSAttribute(S, type); 3154c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3155c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31561b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) { 315787c44604325578b8de07d768391c1c9432404f5aChandler Carruth ParmVarDecl *param = dyn_cast<ParmVarDecl>(D); 3158c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!param) { 315987c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3160768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedParameter; 3161c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3162c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3163c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3164c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK, cf; 316587c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (Attr.getKind() == AttributeList::AT_ns_consumed) { 3166c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, param->getType()); 3167c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3168c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } else { 3169c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, param->getType()); 3170c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3171c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3172c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3173c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 317487c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type) 3175768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << cf; 3176c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3177c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3178c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3179c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (cf) 3180768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context)); 3181c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall else 3182768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context)); 3183c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3184c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSConsumesSelfAttr(Sema &S, Decl *D, 31861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 318787c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<ObjCMethodDecl>(D)) { 318887c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3189768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << ExpectedMethod; 3190c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 3191c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3192c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3193768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context)); 3194c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall} 3195c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 31961b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleNSReturnsRetainedAttr(Sema &S, Decl *D, 31971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3198b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3199c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall QualType returnType; 3200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 320187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 3202c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = MD->getResultType(); 320387c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) 3204831fb9622581fc3b777848e6b097a0cb23d124deFariborz Jahanian returnType = PD->getType(); 320587c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (S.getLangOptions().ObjCAutoRefCount && hasDeclarator(D) && 320687c44604325578b8de07d768391c1c9432404f5aChandler Carruth (Attr.getKind() == AttributeList::AT_ns_returns_retained)) 3207f85e193739c953358c865005855253af4f68a497John McCall return; // ignore: was handled as a type attribute 320887c44604325578b8de07d768391c1c9432404f5aChandler Carruth else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 3209c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall returnType = FD->getResultType(); 32105dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 321187c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type) 3212768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() 3213883cc2ca5ff06d7f1d89a9ab24a2da37f095243bJohn McCall << ExpectedFunctionOrMethod; 3214b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3215b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 3216bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3217c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool typeOK; 3218c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall bool cf; 321987c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3220c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall default: llvm_unreachable("invalid ownership attribute"); return; 3221c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3222c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_retained: 3223c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_not_retained: 3224c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfNSAttribute(S, returnType); 3225c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = false; 3226c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3227c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3228c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_retained: 3229c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_returns_not_retained: 3230c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall typeOK = isValidSubjectOfCFAttribute(S, returnType); 3231c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall cf = true; 3232c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall break; 3233c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall } 3234c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3235c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall if (!typeOK) { 323687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3237768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << isa<ObjCMethodDecl>(D) << cf; 3238bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 32395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 3240bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 324187c44604325578b8de07d768391c1c9432404f5aChandler Carruth switch (Attr.getKind()) { 3242b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 3243b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("invalid ownership attribute"); 3244c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 3245768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(), 3246c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall S.Context)); 3247c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall return; 324831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3249768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(), 3250f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 325131c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 325231c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 3253768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(), 3254f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 325531c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek return; 3256b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 3257768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(), 3258f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3259b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3260b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3261768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(), 3262f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christopher S.Context)); 3263b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 3264b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 3265b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 3266b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3267dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, 3268dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall const AttributeList &attr) { 3269dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall SourceLocation loc = attr.getLoc(); 3270dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3271dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); 3272dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3273dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall if (!isa<ObjCMethodDecl>(method)) { 3274dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::err_attribute_wrong_decl_type) 3275dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc, loc) << attr.getName() << 13 /* methods */; 3276dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3277dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3278dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3279dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Check that the method returns a normal pointer. 3280dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall QualType resultType = method->getResultType(); 3281f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian 3282f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian if (!resultType->isReferenceType() && 3283f2e5945e3a989e9d981c03c4a9cbbfb6232c8c07Fariborz Jahanian (!resultType->isPointerType() || resultType->isObjCRetainableType())) { 3284dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) 3285dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << SourceRange(loc) 3286dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; 3287dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3288dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall // Drop the attribute. 3289dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall return; 3290dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall } 3291dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3292dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall method->addAttr( 3293768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context)); 3294dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall} 3295dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 32968dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall/// Handle cf_audited_transfer and cf_unknown_transfer. 32978dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCallstatic void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) { 32988dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (!isa<FunctionDecl>(D)) { 32998dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 33008dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << A.getName() << 0 /*function*/; 33018dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33028dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33038dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33048dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall bool IsAudited = (A.getKind() == AttributeList::AT_cf_audited_transfer); 33058dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33068dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // Check whether there's a conflicting attribute already present. 33078dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Attr *Existing; 33088dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33098dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFUnknownTransferAttr>(); 33108dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 33118dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall Existing = D->getAttr<CFAuditedTransferAttr>(); 33128dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33138dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (Existing) { 33148dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible) 33158dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getName() 33168dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer") 33178dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall << A.getRange() << Existing->getRange(); 33188dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall return; 33198dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33208dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 33218dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall // All clear; add the attribute. 33228dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall if (IsAudited) { 33238dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 33248dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context)); 33258dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } else { 33268dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall D->addAttr( 33278dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context)); 33288dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall } 33298dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall} 33308dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3331fe98da0fa352462c02db037360788748f95466f7John McCallstatic void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, 3332fe98da0fa352462c02db037360788748f95466f7John McCall const AttributeList &Attr) { 3333fe98da0fa352462c02db037360788748f95466f7John McCall RecordDecl *RD = dyn_cast<RecordDecl>(D); 3334fe98da0fa352462c02db037360788748f95466f7John McCall if (!RD || RD->isUnion()) { 3335fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3336fe98da0fa352462c02db037360788748f95466f7John McCall << Attr.getRange() << Attr.getName() << 14 /*struct */; 3337fe98da0fa352462c02db037360788748f95466f7John McCall } 3338fe98da0fa352462c02db037360788748f95466f7John McCall 3339fe98da0fa352462c02db037360788748f95466f7John McCall IdentifierInfo *ParmName = Attr.getParameterName(); 3340fe98da0fa352462c02db037360788748f95466f7John McCall 3341fe98da0fa352462c02db037360788748f95466f7John McCall // In Objective-C, verify that the type names an Objective-C type. 3342fe98da0fa352462c02db037360788748f95466f7John McCall // We don't want to check this outside of ObjC because people sometimes 3343fe98da0fa352462c02db037360788748f95466f7John McCall // do crazy C declarations of Objective-C types. 3344fe98da0fa352462c02db037360788748f95466f7John McCall if (ParmName && S.getLangOptions().ObjC1) { 3345fe98da0fa352462c02db037360788748f95466f7John McCall // Check for an existing type with this name. 3346fe98da0fa352462c02db037360788748f95466f7John McCall LookupResult R(S, DeclarationName(ParmName), Attr.getParameterLoc(), 3347fe98da0fa352462c02db037360788748f95466f7John McCall Sema::LookupOrdinaryName); 3348fe98da0fa352462c02db037360788748f95466f7John McCall if (S.LookupName(R, Sc)) { 3349fe98da0fa352462c02db037360788748f95466f7John McCall NamedDecl *Target = R.getFoundDecl(); 3350fe98da0fa352462c02db037360788748f95466f7John McCall if (Target && !isa<ObjCInterfaceDecl>(Target)) { 3351fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface); 3352fe98da0fa352462c02db037360788748f95466f7John McCall S.Diag(Target->getLocStart(), diag::note_declared_at); 3353fe98da0fa352462c02db037360788748f95466f7John McCall } 3354fe98da0fa352462c02db037360788748f95466f7John McCall } 3355fe98da0fa352462c02db037360788748f95466f7John McCall } 3356fe98da0fa352462c02db037360788748f95466f7John McCall 3357fe98da0fa352462c02db037360788748f95466f7John McCall D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context, 3358fe98da0fa352462c02db037360788748f95466f7John McCall ParmName)); 3359fe98da0fa352462c02db037360788748f95466f7John McCall} 3360fe98da0fa352462c02db037360788748f95466f7John McCall 33611b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCOwnershipAttr(Sema &S, Decl *D, 33621b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 336387c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (hasDeclarator(D)) return; 3364f85e193739c953358c865005855253af4f68a497John McCall 336587c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3366768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << 12 /* variable */; 3367f85e193739c953358c865005855253af4f68a497John McCall} 3368f85e193739c953358c865005855253af4f68a497John McCall 33691b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, 33701b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 337187c44604325578b8de07d768391c1c9432404f5aChandler Carruth if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) { 337287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) 3373768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis << Attr.getRange() << Attr.getName() << 12 /* variable */; 3374f85e193739c953358c865005855253af4f68a497John McCall return; 3375f85e193739c953358c865005855253af4f68a497John McCall } 3376f85e193739c953358c865005855253af4f68a497John McCall 337787c44604325578b8de07d768391c1c9432404f5aChandler Carruth ValueDecl *vd = cast<ValueDecl>(D); 3378f85e193739c953358c865005855253af4f68a497John McCall QualType type = vd->getType(); 3379f85e193739c953358c865005855253af4f68a497John McCall 3380f85e193739c953358c865005855253af4f68a497John McCall if (!type->isDependentType() && 3381f85e193739c953358c865005855253af4f68a497John McCall !type->isObjCLifetimeType()) { 338287c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::err_objc_precise_lifetime_bad_type) 3383f85e193739c953358c865005855253af4f68a497John McCall << type; 3384f85e193739c953358c865005855253af4f68a497John McCall return; 3385f85e193739c953358c865005855253af4f68a497John McCall } 3386f85e193739c953358c865005855253af4f68a497John McCall 3387f85e193739c953358c865005855253af4f68a497John McCall Qualifiers::ObjCLifetime lifetime = type.getObjCLifetime(); 3388f85e193739c953358c865005855253af4f68a497John McCall 3389f85e193739c953358c865005855253af4f68a497John McCall // If we have no lifetime yet, check the lifetime we're presumably 3390f85e193739c953358c865005855253af4f68a497John McCall // going to infer. 3391f85e193739c953358c865005855253af4f68a497John McCall if (lifetime == Qualifiers::OCL_None && !type->isDependentType()) 3392f85e193739c953358c865005855253af4f68a497John McCall lifetime = type->getObjCARCImplicitLifetime(); 3393f85e193739c953358c865005855253af4f68a497John McCall 3394f85e193739c953358c865005855253af4f68a497John McCall switch (lifetime) { 3395f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_None: 3396f85e193739c953358c865005855253af4f68a497John McCall assert(type->isDependentType() && 3397f85e193739c953358c865005855253af4f68a497John McCall "didn't infer lifetime for non-dependent type?"); 3398f85e193739c953358c865005855253af4f68a497John McCall break; 3399f85e193739c953358c865005855253af4f68a497John McCall 3400f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Weak: // meaningful 3401f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Strong: // meaningful 3402f85e193739c953358c865005855253af4f68a497John McCall break; 3403f85e193739c953358c865005855253af4f68a497John McCall 3404f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_ExplicitNone: 3405f85e193739c953358c865005855253af4f68a497John McCall case Qualifiers::OCL_Autoreleasing: 340687c44604325578b8de07d768391c1c9432404f5aChandler Carruth S.Diag(Attr.getLoc(), diag::warn_objc_precise_lifetime_meaningless) 3407f85e193739c953358c865005855253af4f68a497John McCall << (lifetime == Qualifiers::OCL_Autoreleasing); 3408f85e193739c953358c865005855253af4f68a497John McCall break; 3409f85e193739c953358c865005855253af4f68a497John McCall } 3410f85e193739c953358c865005855253af4f68a497John McCall 341187c44604325578b8de07d768391c1c9432404f5aChandler Carruth D->addAttr(::new (S.Context) 3412768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); 3413f85e193739c953358c865005855253af4f68a497John McCall} 3414f85e193739c953358c865005855253af4f68a497John McCall 3415f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davisstatic bool isKnownDeclSpecAttr(const AttributeList &Attr) { 3416f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis return Attr.getKind() == AttributeList::AT_dllimport || 341711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_dllexport || 341811542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Attr.getKind() == AttributeList::AT_uuid; 341911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet} 342011542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 342111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 342211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet// Microsoft specific attribute handlers. 342311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet//===----------------------------------------------------------------------===// 342411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 34251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) { 342662ec1f2fd7368542bb926c04797fb07023547694Francois Pichet if (S.LangOpts.MicrosoftExt || S.LangOpts.Borland) { 342711542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet // check the attribute arguments. 34281731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth if (!checkAttributeNumArgs(S, Attr, 1)) 342911542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet return; 34301731e202b268bfcd883710e2b10fe44a869bbcb7Chandler Carruth 343111542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Expr *Arg = Attr.getArg(0); 343211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 34335cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor if (!Str || !Str->isAscii()) { 3434d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3435d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet << "uuid" << 1; 3436d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3437d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3438d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 34395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef StrRef = Str->getString(); 3440d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3441d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' && 3442d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet StrRef.back() == '}'; 3443d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3444d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // Validate GUID length. 3445d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (IsCurly && StrRef.size() != 38) { 3446d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3447d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3448d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3449d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (!IsCurly && StrRef.size() != 36) { 3450d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3451d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3452d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3453d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet 3454d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 3455d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" 34565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::iterator I = StrRef.begin(); 3457f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson if (IsCurly) // Skip the optional '{' 3458f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson ++I; 3459f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson 3460f89e0424b8903438179f4a2f16dddd5e5bdc814eAnders Carlsson for (int i = 0; i < 36; ++i) { 3461d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (i == 8 || i == 13 || i == 18 || i == 23) { 3462d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet if (*I != '-') { 3463d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3464d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3465d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3466d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else if (!isxdigit(*I)) { 3467d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid); 3468d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet return; 3469d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 3470d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet I++; 3471d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } 347211542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet 3473768d6cae40ad4ff3aed5483269d068ff7a45e229Argyrios Kyrtzidis D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context, 347411542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet Str->getString())); 3475d3d3be9bc717b37366324e9711f1ea22dea42caaFrancois Pichet } else 347611542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid"; 3477f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis} 3478f0122fe49329cb439d55a6712bfcaad9a6570428Charles Davis 3479b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 34800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 34810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 34820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 34831b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessNonInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 34841b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 348560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne switch (Attr.getKind()) { 34861b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_device: handleDeviceAttr (S, D, Attr); break; 34871b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_host: handleHostAttr (S, D, Attr); break; 34881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_overloadable:handleOverloadableAttr(S, D, Attr); break; 348960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne default: 349060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 349160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne } 349260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 3493e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481Abramo Bagnara 34941b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, 34951b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr) { 3496803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 34971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_IBAction: handleIBAction(S, D, Attr); break; 34981b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break; 3499857e918a8a40deb128840308a318bf623d68295fTed Kremenek case AttributeList::AT_IBOutletCollection: 35001b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleIBOutletCollection(S, D, Attr); break; 3501803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 3502207f4d8543529221932af82836016a2ef066c917Peter Collingbourne case AttributeList::AT_opencl_image_access: 3503ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 35046e132aab867c189b1c3ee7463ef9d2b1f03a294dJohn Thompson case AttributeList::AT_vector_size: 35054211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_vector_type: 35064211bb68cff1f310be280f66a59520548ef99d8fBob Wilson case AttributeList::AT_neon_polyvector_type: 3507bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 3508bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 3509803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 351060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_device: 351160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_host: 351260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne case AttributeList::AT_overloadable: 351360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // Ignore, this is a non-inheritable attribute, handled 351460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // by ProcessNonInheritableDeclAttr. 351560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne break; 35161b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_alias: handleAliasAttr (S, D, Attr); break; 35171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_aligned: handleAlignedAttr (S, D, Attr); break; 3518bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 35191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAlwaysInlineAttr (S, D, Attr); break; 3520b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 35211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleAnalyzerNoReturnAttr (S, D, Attr); break; 35221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_annotate: handleAnnotateAttr (S, D, Attr); break; 35231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_availability:handleAvailabilityAttr(S, D, Attr); break; 3524bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt case AttributeList::AT_carries_dependency: 35251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleDependencyAttr (S, D, Attr); break; 35261b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_common: handleCommonAttr (S, D, Attr); break; 35271b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constant: handleConstantAttr (S, D, Attr); break; 35281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_constructor: handleConstructorAttr (S, D, Attr); break; 35291b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_deprecated: handleDeprecatedAttr (S, D, Attr); break; 35301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_destructor: handleDestructorAttr (S, D, Attr); break; 35313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 35321b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleExtVectorTypeAttr(S, scope, D, Attr); 35333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 35341b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format: handleFormatAttr (S, D, Attr); break; 35351b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_format_arg: handleFormatArgAttr (S, D, Attr); break; 35361b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_global: handleGlobalAttr (S, D, Attr); break; 35371b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_gnu_inline: handleGNUInlineAttr (S, D, Attr); break; 35387b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne case AttributeList::AT_launch_bounds: 35391b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleLaunchBoundsAttr(S, D, Attr); 35407b381985353304a7723acb05911ff91634fa1f27Peter Collingbourne break; 35411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_mode: handleModeAttr (S, D, Attr); break; 35421b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_malloc: handleMallocAttr (S, D, Attr); break; 35431b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_may_alias: handleMayAliasAttr (S, D, Attr); break; 35441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nocommon: handleNoCommonAttr (S, D, Attr); break; 35451b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nonnull: handleNonNullAttr (S, D, Attr); break; 3546dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_returns: 3547dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_takes: 3548dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek case AttributeList::AT_ownership_holds: 35491b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOwnershipAttr (S, D, Attr); break; 35501b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_naked: handleNakedAttr (S, D, Attr); break; 35511b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noreturn: handleNoReturnAttr (S, D, Attr); break; 35521b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nothrow: handleNothrowAttr (S, D, Attr); break; 35531b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_shared: handleSharedAttr (S, D, Attr); break; 35541b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_vecreturn: handleVecReturnAttr (S, D, Attr); break; 3555b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 3556b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis case AttributeList::AT_objc_ownership: 35571b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCOwnershipAttr(S, D, Attr); break; 3558f85e193739c953358c865005855253af4f68a497John McCall case AttributeList::AT_objc_precise_lifetime: 35591b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCPreciseLifetimeAttr(S, D, Attr); break; 3560f85e193739c953358c865005855253af4f68a497John McCall 3561dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall case AttributeList::AT_objc_returns_inner_pointer: 3562dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall handleObjCReturnsInnerPointerAttr(S, D, Attr); break; 3563dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall 3564fe98da0fa352462c02db037360788748f95466f7John McCall case AttributeList::AT_ns_bridged: 3565fe98da0fa352462c02db037360788748f95466f7John McCall handleNSBridgedAttr(S, scope, D, Attr); break; 3566fe98da0fa352462c02db037360788748f95466f7John McCall 35678dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_audited_transfer: 35688dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall case AttributeList::AT_cf_unknown_transfer: 35698dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall handleCFTransferAttr(S, D, Attr); break; 35708dfac0baaf0f81d3945bcb306480e358ba8d1f08John McCall 3571b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 3572c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_cf_consumed: 35731b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_ns_consumed: handleNSConsumedAttr (S, D, Attr); break; 3574c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_consumes_self: 35751b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSConsumesSelfAttr(S, D, Attr); break; 3576c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall 3577c7ad38168d329d778e884a8b6400bcbed8dc85eeJohn McCall case AttributeList::AT_ns_returns_autoreleased: 357831c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_ns_returns_not_retained: 357931c780d95a830f0187cfcbb1016ce88f50a7dfe1Ted Kremenek case AttributeList::AT_cf_returns_not_retained: 3580b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 3581b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 35821b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNSReturnsRetainedAttr(S, D, Attr); break; 3583b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 35846f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 35851b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleReqdWorkGroupSize(S, D, Attr); break; 35866f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 3587521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian case AttributeList::AT_init_priority: 35881b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleInitPriorityAttr(S, D, Attr); break; 3589521f12d3dfdbb0e93d1bcb503d074e67acdc489cFariborz Jahanian 35901b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_packed: handlePackedAttr (S, D, Attr); break; 35911b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break; 35921b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; 35931b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; 3594742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian case AttributeList::AT_arc_weakref_unavailable: 3595742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian handleArcWeakrefUnavailableAttr (S, D, Attr); 3596742352a3984aeef9ecf911be23e673e97b34595fFariborz Jahanian break; 35971b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; 3598f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola case AttributeList::AT_returns_twice: 3599f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola handleReturnsTwiceAttr(S, D, Attr); 3600f87cced71a955dca5731e7b28bc182e4824c0355Rafael Espindola break; 36011b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; 36021b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; 36031b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_warn_unused_result: handleWarnUnusedResult(S, D, Attr); 3604026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 36051b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak: handleWeakAttr (S, D, Attr); break; 36061b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weakref: handleWeakRefAttr (S, D, Attr); break; 36071b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_weak_import: handleWeakImportAttr (S, D, Attr); break; 3608803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 36091b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleTransparentUnionAttr(S, D, Attr); 3610803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 36110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 36121b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCExceptionAttr(S, D, Attr); 36130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 3614d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall case AttributeList::AT_objc_method_family: 36151b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleObjCMethodFamilyAttr(S, D, Attr); 3616d5313b0bbf3948fe7c63bf46a7da330c96d07309John McCall break; 36171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nsobject: handleObjCNSObject (S, D, Attr); break; 36181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_blocks: handleBlocksAttr (S, D, Attr); break; 36191b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_sentinel: handleSentinelAttr (S, D, Attr); break; 36201b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_const: handleConstAttr (S, D, Attr); break; 36211b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_pure: handlePureAttr (S, D, Attr); break; 36221b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_cleanup: handleCleanupAttr (S, D, Attr); break; 36231b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_nodebug: handleNoDebugAttr (S, D, Attr); break; 36241b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_noinline: handleNoInlineAttr (S, D, Attr); break; 36251b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth case AttributeList::AT_regparm: handleRegparmAttr (S, D, Attr); break; 3626bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 362705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 362805f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 36297255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 36301b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleNoInstrumentFunctionAttr(S, D, Attr); 36317255a2d997b15beae82e627052fdb1b2474495c2Chris Lattner break; 363204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_stdcall: 363304a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_cdecl: 363404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall case AttributeList::AT_fastcall: 3635f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor case AttributeList::AT_thiscall: 363652fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik case AttributeList::AT_pascal: 3637414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov case AttributeList::AT_pcs: 36381b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleCallConvAttr(S, D, Attr); 363904a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall break; 3640f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne case AttributeList::AT_opencl_kernel_function: 36411b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleOpenCLKernelAttr(S, D, Attr); 3642f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne break; 364311542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet case AttributeList::AT_uuid: 36441b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth handleUuidAttr(S, D, Attr); 364511542141e385859df6b4f1a8f1f01856ad193b5bFrancois Pichet break; 3646fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3647fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski // Thread safety attributes: 3648fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_guarded_var: 3649fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr); 3650fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3651fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_pt_guarded_var: 3652fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleGuardedVarAttr(S, D, Attr, /*pointer = */true); 3653fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3654fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_scoped_lockable: 3655fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr, /*scoped = */true); 3656fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3657fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_no_thread_safety_analysis: 3658fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleNoThreadSafetyAttr(S, D, Attr); 3659fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3660fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski case AttributeList::AT_lockable: 3661fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski handleLockableAttr(S, D, Attr); 3662fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski break; 3663db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_guarded_by: 3664db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr); 3665db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3666db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_pt_guarded_by: 3667db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleGuardedByAttr(S, D, Attr, /*pointer = */true); 3668db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3669db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_lock_function: 3670db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr, /*exclusive = */true); 3671db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3672db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_locks_required: 3673db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr, /*exclusive = */true); 3674db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3675db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_exclusive_trylock_function: 3676db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr, /*exclusive = */true); 3677db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3678db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_lock_returned: 3679db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockReturnedAttr(S, D, Attr); 3680db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3681db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_locks_excluded: 3682db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksExcludedAttr(S, D, Attr); 3683db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3684db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_lock_function: 3685db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLockFunAttr(S, D, Attr); 3686db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3687db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_locks_required: 3688db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleLocksRequiredAttr(S, D, Attr); 3689db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3690db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_shared_trylock_function: 3691db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleTrylockFunAttr(S, D, Attr); 3692db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3693db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_unlock_function: 3694db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleUnlockFunAttr(S, D, Attr); 3695db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3696db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_before: 3697db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */true); 3698db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3699db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski case AttributeList::AT_acquired_after: 3700db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski handleAcquireOrderAttr(S, D, Attr, /*before = */false); 3701db33e14661c7a118a2d9a777ae69c0ecaa036e1eCaitlin Sadowski break; 3702fdde9e719ad75e656a1475a36b06c2f88f0957ccCaitlin Sadowski 3703803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 370482d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov // Ask target about the attribute. 370582d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); 370682d0a418c8699fc6f4a9417457ffe93d43bba1c1Anton Korobeynikov if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) 37077d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) 37087d5c45ed9dc2842ce8e65ea26ced0957be36a569Chandler Carruth << Attr.getName(); 3709803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 3710803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 371360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 371460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the attribute applies to decls. If the attribute is a type attribute, just 371560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to 371660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). 37171b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruthstatic void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 37181b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth const AttributeList &Attr, 371960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 372060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isInvalid()) 372160700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 372260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 372360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) 372460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne // FIXME: Try to deal with other __declspec attributes! 372560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne return; 372660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 372760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (NonInheritable) 37281b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessNonInheritableDeclAttr(S, scope, D, Attr); 372960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 373060700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable) 37311b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessInheritableDeclAttr(S, scope, D, Attr); 373260700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne} 373360700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne 3734803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 3735803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 3736f48f367cfe096fd307d36aff27d2d5a00e830571Eric Christophervoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, 373760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne const AttributeList *AttrList, 373860700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 373911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola for (const AttributeList* l = AttrList; l; l = l->getNext()) { 37401b03c8719e2e45cf2769430335d7e71f18e6634aChandler Carruth ProcessDeclAttribute(*this, S, D, *l, NonInheritable, Inheritable); 374111e8ce7380856abee188b237c2600272df2ed09dRafael Espindola } 374211e8ce7380856abee188b237c2600272df2ed09dRafael Espindola 374311e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // GCC accepts 374411e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // static int a9 __attribute__((weakref)); 374511e8ce7380856abee188b237c2600272df2ed09dRafael Espindola // but that looks really pointless. We reject it. 374660700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne if (Inheritable && D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) { 374711e8ce7380856abee188b237c2600272df2ed09dRafael Espindola Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) << 3748dd0e490c24aeade2c59ca4cae171199f6af9f02eTed Kremenek dyn_cast<NamedDecl>(D)->getNameAsString(); 374911e8ce7380856abee188b237c2600272df2ed09dRafael Espindola return; 3750803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 3751803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 3752803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 37535f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// Annotation attributes are the only attributes allowed after an access 37545f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// specifier. 37555f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggenbool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, 37565f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen const AttributeList *AttrList) { 37575f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen for (const AttributeList* l = AttrList; l; l = l->getNext()) { 37585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (l->getKind() == AttributeList::AT_annotate) { 37595f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen handleAnnotateAttr(*this, ASDecl, *l); 37605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } else { 37615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Diag(l->getLoc(), diag::err_only_annotate_after_access_spec); 37625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return true; 37635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 37645f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen } 37655f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 37665f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return false; 37675f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen} 37685f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 3769e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Check a list of attributes to see if it 3770e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// contains any decl attributes that we should warn about. 3771e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallstatic void checkUnusedDeclAttributes(Sema &S, const AttributeList *A) { 3772e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for ( ; A; A = A->getNext()) { 3773e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall // Only warn if the attribute is an unignored, non-type attribute. 3774e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->isUsedAsTypeAttr()) continue; 3775e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::IgnoredAttribute) continue; 3776e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3777e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall if (A->getKind() == AttributeList::UnknownAttribute) { 3778e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_unknown_attribute_ignored) 3779e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3780e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } else { 3781e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall S.Diag(A->getLoc(), diag::warn_attribute_not_on_decl) 3782e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall << A->getName() << A->getRange(); 3783e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3784e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall } 3785e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3786e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3787e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// checkUnusedDeclAttributes - Given a declarator which is not being 3788e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// used to build a declaration, complain about any decl attributes 3789e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall/// which might be lying around on it. 3790e82247a71a1a76e78f3b979b64d5f6412ab40266John McCallvoid Sema::checkUnusedDeclAttributes(Declarator &D) { 3791e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getDeclSpec().getAttributes().getList()); 3792e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getAttributes()); 3793e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) 3794e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall ::checkUnusedDeclAttributes(*this, D.getTypeObject(i).getAttrs()); 3795e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall} 3796e82247a71a1a76e78f3b979b64d5f6412ab40266John McCall 3797e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 3798e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 3799900693b715b3832a42ae87157332baece94ccdd8Eli FriedmanNamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II, 3800900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SourceLocation Loc) { 38017b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 3802e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 3803e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 3804900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FunctionDecl *NewFD; 3805900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Missing call to CheckFunctionDeclaration(). 3806900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Mangling? 3807900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the qualifier info correct? 3808900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // FIXME: Is the DeclContext correct? 3809900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 3810900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Loc, Loc, DeclarationName(II), 3811900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->getType(), FD->getTypeSourceInfo(), 3812900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SC_None, SC_None, 3813900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isInlineSpecified*/, 3814900693b715b3832a42ae87157332baece94ccdd8Eli Friedman FD->hasPrototype(), 3815900693b715b3832a42ae87157332baece94ccdd8Eli Friedman false/*isConstexprSpecified*/); 3816900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NewD = NewFD; 3817900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3818900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (FD->getQualifier()) 3819c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewFD->setQualifierInfo(FD->getQualifierLoc()); 3820900693b715b3832a42ae87157332baece94ccdd8Eli Friedman 3821900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // Fake up parameter variables; they are declared as if this were 3822900693b715b3832a42ae87157332baece94ccdd8Eli Friedman // a typedef. 3823900693b715b3832a42ae87157332baece94ccdd8Eli Friedman QualType FDTy = FD->getType(); 3824900693b715b3832a42ae87157332baece94ccdd8Eli Friedman if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) { 3825900693b715b3832a42ae87157332baece94ccdd8Eli Friedman SmallVector<ParmVarDecl*, 16> Params; 3826900693b715b3832a42ae87157332baece94ccdd8Eli Friedman for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), 3827900693b715b3832a42ae87157332baece94ccdd8Eli Friedman AE = FT->arg_type_end(); AI != AE; ++AI) { 3828900693b715b3832a42ae87157332baece94ccdd8Eli Friedman ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI); 3829900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Param->setScopeInfo(0, Params.size()); 3830900693b715b3832a42ae87157332baece94ccdd8Eli Friedman Params.push_back(Param); 3831900693b715b3832a42ae87157332baece94ccdd8Eli Friedman } 38324278c654b645402554eb52a48e9c7097c9f1233aDavid Blaikie NewFD->setParams(Params); 3833b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3834e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 3835e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 3836ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara VD->getInnerLocStart(), VD->getLocation(), II, 3837a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall VD->getType(), VD->getTypeSourceInfo(), 383816573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClass(), 383916573fa9705b546b7597c273b25b85d6321e2b33Douglas Gregor VD->getStorageClassAsWritten()); 3840b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall if (VD->getQualifier()) { 3841b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall VarDecl *NewVD = cast<VarDecl>(NewD); 3842c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor NewVD->setQualifierInfo(VD->getQualifierLoc()); 3843b6217665c6a987f2d6c8665fd70365d7719ac4dfJohn McCall } 3844e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3845e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 3846e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3847e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 3848e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 3849e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 38507b1fdbda2757cc4a7f25664475be44119d7f8e59Ryan Flynnvoid Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { 3851c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getUsed()) return; // only do this once 3852c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner W.setUsed(true); 3853c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 3854c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner IdentifierInfo *NDId = ND->getIdentifier(); 3855900693b715b3832a42ae87157332baece94ccdd8Eli Friedman NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation()); 3856cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context, 3857cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NDId->getName())); 3858cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3859c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner WeakTopLevelDecl.push_back(NewD); 3860c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // FIXME: "hideous" code from Sema::LazilyCreateBuiltin 3861c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner // to insert Decl at TU scope, sorry. 3862c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner DeclContext *SavedContext = CurContext; 3863c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = Context.getTranslationUnitDecl(); 3864c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner PushOnScopeChains(NewD, S); 3865c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner CurContext = SavedContext; 3866c4f1fb125d4fe2c8879030d6f6e8b2f75cb681f1Chris Lattner } else { // just add weak to existing 3867cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context)); 3868e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3869e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 3870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 38710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 38720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 38730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 387460700390a787471d3396f380e0679a6d08c27f1fPeter Collingbournevoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, 387560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne bool NonInheritable, bool Inheritable) { 3876d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // It's valid to "forward-declare" #pragma weak, in which case we 3877d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall // have to do this. 387831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (Inheritable) { 387931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor LoadExternalWeakUndeclaredIdentifiers(); 388031e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (!WeakUndeclaredIdentifiers.empty()) { 388131e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 388231e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (IdentifierInfo *Id = ND->getIdentifier()) { 388331e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator I 388431e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor = WeakUndeclaredIdentifiers.find(Id); 388531e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor if (I != WeakUndeclaredIdentifiers.end() && ND->hasLinkage()) { 388631e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakInfo W = I->second; 388731e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor DeclApplyPragmaWeak(S, ND, W); 388831e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor WeakUndeclaredIdentifiers[Id] = W; 388931e37b2d7b4815fdea6a35d49f33005562f0d494Douglas Gregor } 3890d4aff0e2b77879e27e7e4eac8c972aaaa293fa12John McCall } 3891e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3892e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3893e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 3894e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 38950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 38967f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) 389760700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3898bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 38990744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 39000744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 39010744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 39020744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 39030744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 39040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 390560700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 3906bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 39070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 39080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 390960700390a787471d3396f380e0679a6d08c27f1fPeter Collingbourne ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); 39100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 391154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3912f85e193739c953358c865005855253af4f68a497John McCall/// Is the given declaration allowed to use a forbidden type? 3913f85e193739c953358c865005855253af4f68a497John McCallstatic bool isForbiddenTypeAllowed(Sema &S, Decl *decl) { 3914f85e193739c953358c865005855253af4f68a497John McCall // Private ivars are always okay. Unfortunately, people don't 3915f85e193739c953358c865005855253af4f68a497John McCall // always properly make their ivars private, even in system headers. 3916f85e193739c953358c865005855253af4f68a497John McCall // Plus we need to make fields okay, too. 3917a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian // Function declarations in sys headers will be marked unavailable. 3918a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) && 3919a6b33808ef7e80ab68a052c97dab9077dca159c5Fariborz Jahanian !isa<FunctionDecl>(decl)) 3920f85e193739c953358c865005855253af4f68a497John McCall return false; 3921f85e193739c953358c865005855253af4f68a497John McCall 3922f85e193739c953358c865005855253af4f68a497John McCall // Require it to be declared in a system header. 3923f85e193739c953358c865005855253af4f68a497John McCall return S.Context.getSourceManager().isInSystemHeader(decl->getLocation()); 3924f85e193739c953358c865005855253af4f68a497John McCall} 3925f85e193739c953358c865005855253af4f68a497John McCall 3926f85e193739c953358c865005855253af4f68a497John McCall/// Handle a delayed forbidden-type diagnostic. 3927f85e193739c953358c865005855253af4f68a497John McCallstatic void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag, 3928f85e193739c953358c865005855253af4f68a497John McCall Decl *decl) { 3929f85e193739c953358c865005855253af4f68a497John McCall if (decl && isForbiddenTypeAllowed(S, decl)) { 3930f85e193739c953358c865005855253af4f68a497John McCall decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context, 3931f85e193739c953358c865005855253af4f68a497John McCall "this system declaration uses an unsupported type")); 3932f85e193739c953358c865005855253af4f68a497John McCall return; 3933f85e193739c953358c865005855253af4f68a497John McCall } 3934175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (S.getLangOptions().ObjCAutoRefCount) 3935175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(decl)) { 3936175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // FIXME. we may want to supress diagnostics for all 3937175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian // kind of forbidden type messages on unavailable functions. 3938175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian if (FD->hasAttr<UnavailableAttr>() && 3939175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.getForbiddenTypeDiagnostic() == 3940175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag::err_arc_array_param_no_ownership) { 3941175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian diag.Triggered = true; 3942175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian return; 3943175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 3944175fb1070be0ee24a75064b118f0e13fbe354200Fariborz Jahanian } 3945f85e193739c953358c865005855253af4f68a497John McCall 3946f85e193739c953358c865005855253af4f68a497John McCall S.Diag(diag.Loc, diag.getForbiddenTypeDiagnostic()) 3947f85e193739c953358c865005855253af4f68a497John McCall << diag.getForbiddenTypeOperand() << diag.getForbiddenTypeArgument(); 3948f85e193739c953358c865005855253af4f68a497John McCall diag.Triggered = true; 3949f85e193739c953358c865005855253af4f68a497John McCall} 3950f85e193739c953358c865005855253af4f68a497John McCall 3951eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// This duplicates a vector push_back but hides the need to know the 3952eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall// size of the type. 3953eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::add(const DelayedDiagnostic &diag) { 3954eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize <= StackCapacity); 3955eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3956eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Grow the stack if necessary. 3957eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackSize == StackCapacity) { 3958eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall unsigned newCapacity = 2 * StackCapacity + 2; 3959eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall char *newBuffer = new char[newCapacity * sizeof(DelayedDiagnostic)]; 3960eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall const char *oldBuffer = (const char*) Stack; 3961eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3962eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (StackCapacity) 3963eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall memcpy(newBuffer, oldBuffer, StackCapacity * sizeof(DelayedDiagnostic)); 3964eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3965eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall delete[] oldBuffer; 3966eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Stack = reinterpret_cast<sema::DelayedDiagnostic*>(newBuffer); 3967eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall StackCapacity = newCapacity; 3968eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall } 3969eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 3970eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(StackSize < StackCapacity); 3971eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall new (&Stack[StackSize++]) DelayedDiagnostic(diag); 397254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 397354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3974eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Sema::DelayedDiagnostics::popParsingDecl(Sema &S, ParsingDeclState state, 3975eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Decl *decl) { 3976eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics &DD = S.DelayedDiagnostics; 397754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3978eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Check the invariants. 3979eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.StackSize >= state.SavedStackSize); 3980eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(state.SavedStackSize >= DD.ActiveStackBase); 3981eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall assert(DD.ParsingDepth > 0); 398254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3983eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // Drop the parsing depth. 3984eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.ParsingDepth--; 398554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 3986eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // If there are no active diagnostics, we're done. 3987eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DD.StackSize == DD.ActiveStackBase) 3988eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return; 398958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 39902f514480c448708ec382a684cf5e035d3a827ec8John McCall // We only want to actually emit delayed diagnostics when we 39912f514480c448708ec382a684cf5e035d3a827ec8John McCall // successfully parsed a decl. 3992a7bf7bbdb1f89c35a09bc525c6862525ae82778fArgyrios Kyrtzidis if (decl && !decl->isInvalidDecl()) { 3993eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // We emit all the active diagnostics, not just those starting 3994eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall // from the saved state. The idea is this: we get one push for a 39952f514480c448708ec382a684cf5e035d3a827ec8John McCall // decl spec and another for each declarator; in a decl group like: 39962f514480c448708ec382a684cf5e035d3a827ec8John McCall // deprecated_typedef foo, *bar, baz(); 39972f514480c448708ec382a684cf5e035d3a827ec8John McCall // only the declarator pops will be passed decls. This is correct; 39982f514480c448708ec382a684cf5e035d3a827ec8John McCall // we really do need to consider delayed diagnostics from the decl spec 39992f514480c448708ec382a684cf5e035d3a827ec8John McCall // for each of the different declarations. 4000eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = DD.ActiveStackBase, e = DD.StackSize; i != e; ++i) { 4001eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostic &diag = DD.Stack[i]; 4002eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (diag.Triggered) 40032f514480c448708ec382a684cf5e035d3a827ec8John McCall continue; 40042f514480c448708ec382a684cf5e035d3a827ec8John McCall 4005eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall switch (diag.Kind) { 40062f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Deprecation: 4007eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedDeprecationCheck(diag, decl); 40082f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 40092f514480c448708ec382a684cf5e035d3a827ec8John McCall 40102f514480c448708ec382a684cf5e035d3a827ec8John McCall case DelayedDiagnostic::Access: 4011eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall S.HandleDelayedAccessCheck(diag, decl); 40122f514480c448708ec382a684cf5e035d3a827ec8John McCall break; 4013f85e193739c953358c865005855253af4f68a497John McCall 4014f85e193739c953358c865005855253af4f68a497John McCall case DelayedDiagnostic::ForbiddenType: 4015f85e193739c953358c865005855253af4f68a497John McCall handleDelayedForbiddenType(S, diag, decl); 4016f85e193739c953358c865005855253af4f68a497John McCall break; 401754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 401854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 401954abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 402054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 402158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall // Destroy all the delayed diagnostics we're about to pop off. 4022eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall for (unsigned i = state.SavedStackSize, e = DD.StackSize; i != e; ++i) 402329233802236f7fe1db20e00eca4f5cc8f3f64adeDouglas Gregor DD.Stack[i].Destroy(); 402458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall 4025eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DD.StackSize = state.SavedStackSize; 40262f514480c448708ec382a684cf5e035d3a827ec8John McCall} 40272f514480c448708ec382a684cf5e035d3a827ec8John McCall 40282f514480c448708ec382a684cf5e035d3a827ec8John McCallstatic bool isDeclDeprecated(Decl *D) { 40292f514480c448708ec382a684cf5e035d3a827ec8John McCall do { 40300a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (D->isDeprecated()) 40312f514480c448708ec382a684cf5e035d3a827ec8John McCall return true; 4032c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis // A category implicitly has the availability of the interface. 4033c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) 4034c076e37e2223cfe998fa5e657dece30da78fcdc4Argyrios Kyrtzidis return CatD->getClassInterface()->isDeprecated(); 40352f514480c448708ec382a684cf5e035d3a827ec8John McCall } while ((D = cast_or_null<Decl>(D->getDeclContext()))); 40362f514480c448708ec382a684cf5e035d3a827ec8John McCall return false; 40372f514480c448708ec382a684cf5e035d3a827ec8John McCall} 40382f514480c448708ec382a684cf5e035d3a827ec8John McCall 40399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallvoid Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, 40402f514480c448708ec382a684cf5e035d3a827ec8John McCall Decl *Ctx) { 40412f514480c448708ec382a684cf5e035d3a827ec8John McCall if (isDeclDeprecated(Ctx)) 40422f514480c448708ec382a684cf5e035d3a827ec8John McCall return; 40432f514480c448708ec382a684cf5e035d3a827ec8John McCall 40442f514480c448708ec382a684cf5e035d3a827ec8John McCall DD.Triggered = true; 4045ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!DD.getDeprecationMessage().empty()) 4046c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated_message) 4047ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName() 4048ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationMessage(); 4049c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian else 4050c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(DD.Loc, diag::warn_deprecated) 4051ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer << DD.getDeprecationDecl()->getDeclName(); 405254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 405354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 40545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message, 40558e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian SourceLocation Loc, 405689ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian const ObjCInterfaceDecl *UnknownObjCClass) { 405754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Delay if we're currently parsing a declaration. 4058eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall if (DelayedDiagnostics.shouldDelayDiagnostics()) { 4059eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message)); 406054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 406154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall } 406254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall 406354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall // Otherwise, don't warn if our current context is deprecated. 40643a387441ae339363ee5b254658f295e97bd9e913Argyrios Kyrtzidis if (isDeclDeprecated(cast<Decl>(getCurLexicalContext()))) 406554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall return; 4066ce2d186a421526e94d9e417ced141ae6c891cf48Benjamin Kramer if (!Message.empty()) 4067c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian Diag(Loc, diag::warn_deprecated_message) << D->getDeclName() 4068c4b35cfdb977f6427fe0d5725bf104e1b425d72eFariborz Jahanian << Message; 40698e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian else { 4070743b82bf3c500de45715498dbf25f0fb39e71462Peter Collingbourne if (!UnknownObjCClass) 40718e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated) << D->getDeclName(); 407289ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian else { 40738e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName(); 407489ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); 407589ebaed91cca7fd296ec7804e4e9fb68949c1d0eFariborz Jahanian } 40768e5fc9be37c6828ad008f22730e3baac1bef1686Fariborz Jahanian } 407754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall} 4078