SemaDeclAttr.cpp revision 620d89ca4eb5dcb6be13a42aafa4849eaa9b834b
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 146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h" 156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 18fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 1912bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 206e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h> 216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 27d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic const FunctionType *getFunctionType(Decl *d) { 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = Ty->getAsPointerType()->getPointeeType(); 40620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else if (Ty->isBlockPointerType()) 41620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian Ty = Ty->getAsBlockPointerType()->getPointeeType(); 42d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 43d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return Ty->getAsFunctionType(); 446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function 50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 51d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) { 53d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return getFunctionType(d) || isa<ObjCMethodDecl>(d); 54d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 56620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function 57620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C 58620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block. 59620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanianstatic bool isFunctionOrMethodOrBlock(Decl *d) { 60620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (isFunctionOrMethod(d)) 61620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return true; 62620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian // check for block is more involved. 63620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Ty->isBlockPointerType(); 66620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return false; 68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian} 69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock. 73d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) { 74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 7572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else { 77d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar assert(isa<ObjCMethodDecl>(d)); 78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) { 8689951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 8772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 88620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian else if (VarDecl *V = dyn_cast<VarDecl>(d)) { 89620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian QualType Ty = V->getType(); 90620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (Ty->isBlockPointerType()) { 91620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian const FunctionType *FT = 92620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType(); 93620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) 94620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian return Proto->getNumArgs(); 95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 96620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 97620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian assert(false && "getFunctionOrMethodNumArgs - caused by block mishap"); 98620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian } 9989951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 1003568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1013568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1023568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 10389951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 10472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 10589951a86b594513c2a013532ed45d197413b1087Chris Lattner 106620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian 10789951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1093568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1103568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 111d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 11272564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1133568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 1143568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 1153568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1163568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1173568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 120b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 121b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 124b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 1256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 135085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 136085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const PointerType *PT = T->getAsPointerType(); 137085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 138085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 139085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 140085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 141085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 142085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 143085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 144085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 145085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 146085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 147085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 150085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 151e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 152e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 153e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 154e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 159803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 160803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 161545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 162545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 164545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 169545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 1703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 173545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 176fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 177fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "ext_vector_type" << sizeExpr->getSourceRange(); 1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 1816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 182b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 183d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType; 1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 191fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 192fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 1936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 196803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 198803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 201065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 202065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 203065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 204065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 205065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 206065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 207065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 208065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 209065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 210803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 211065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 212065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 213065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 215065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 216065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 217fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 218fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 219065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 220065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 221065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 222065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 223545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 2243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 225065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 227545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 229803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 230fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 231fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << sizeExpr->getSourceRange(); 232065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 236b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 237b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2382db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 2392db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner return; 2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 25282afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner // the base type must be integer or float, and can't already be a vector. 25382afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner if (CurType->isVectorType() || 25482afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 255d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 256065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 258803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 264fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 265fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 266065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 269fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 270fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 271065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 273065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 274065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 275065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 276803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 277065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 278065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 279065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 280065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 281065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 284803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 286545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 2920b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner TD->addAttr(::new (S.Context) PackedAttr(1)); 2936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 297803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 298fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 29908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 3006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 3010b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner FD->addAttr(::new (S.Context) PackedAttr(1)); 3026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 3033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 3046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 30796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 30896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 3093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 31096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 31296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 31396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 31496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 315327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 3160b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) IBOutletAttr()); 31796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 318327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 31996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 32096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 324d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 325fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 330d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 340f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 341eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 343fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 344fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 348eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 349eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 35230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 353eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 355465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 356465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 357eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 35946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, x); 36046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (!T->isPointerType() && !T->isBlockPointerType()) { 361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 362fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 363fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 366eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 369eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 3707fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // If no arguments were specified to __attribute__((nonnull)) then all 3717fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // pointer arguments have a nonnull attribute. 3727fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 37346bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 37446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 37546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (T->isPointerType() || T->isBlockPointerType()) 376d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 37746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 3787fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3797fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3817fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3827fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3847fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3857fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3867fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3877fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3880b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NonNullAttr(start, size)); 389eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 390eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 391803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 393545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 398545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 403fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 4043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4130b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 416af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 417af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 418af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 419af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 4203c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 421af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 422af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 4235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 424c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 4255bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4265dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 4275bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 4285bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 429af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 4300b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlwaysInlineAttr()); 431af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 432af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 433b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 4345dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek Sema &S) { 4356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 436545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 438b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 4396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 440d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 44119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 44219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 44319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (VD == 0 || !VD->getType()->isBlockPointerType()) { 44419c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4455dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 44619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump return false; 44719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 4486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 450b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 451b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 452b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 453b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4545dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (HandleCommonNoReturnAttr(d, Attr, S)) 455b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek d->addAttr(::new (S.Context) NoReturnAttr()); 456b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 457b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 458b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 459b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 4605dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (HandleCommonNoReturnAttr(d, Attr, S)) 461b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 4626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 46473798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 46573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 46673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 46873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 46973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 47073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 471d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 472fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4735dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 47473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 47573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 47673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 4770b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UnusedAttr()); 47873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 47973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 480b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 481b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 482b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 483b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 484b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 485b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 486b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 487b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 488186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 489b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 490b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 491b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 492b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 493b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4945dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 495b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 496b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 497b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 4980b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UsedAttr()); 499b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 500b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 5013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 504fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 505fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 514fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5153c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 5163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 521c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 522fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5270b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) ConstructorAttr(priority)); 5283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 533fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 534fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 543fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 5453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5506782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 551fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5525dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5560b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) DestructorAttr(priority)); 5573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 559803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 561545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 5623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5660b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) DeprecatedAttr()); 5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 569bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 570bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 571bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 572bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 573bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 574bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 575bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 5760b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UnavailableAttr()); 577bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 578bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 579803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 581545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 5823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 586545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 591fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 60908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6130b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) VisibilityAttr(type)); 6146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 6170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 6180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 6190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 6200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 6220db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6230db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 6240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 6250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 6260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6270db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 6280db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6290b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) ObjCExceptionAttr()); 6300db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 6310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6320db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 633fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 634fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 635fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 636fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6370db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 638fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 639fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 640fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian !T->getAsPointerType()->getPointeeType()->isRecordType()) { 641fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 642fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 643fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 644fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6450b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 646fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 647fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 648f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void 649f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 650f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 651f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 652f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 653f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 654f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 655f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 656f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 657f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 658f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 659f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6600b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) OverloadableAttr()); 661f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 662f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (!Attr.getParameterName()) { 665fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 67692e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 679fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 6819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6840b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) BlocksAttr(type)); 6859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 6869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 690fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 691fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 694770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 695770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 700fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 702770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 703770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 707fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 708fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 709770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 710770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 712770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 713770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 717770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 718fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 720770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 724770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 726770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 727fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 728fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 729770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 730770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 731770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 732770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 734897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner const FunctionType *FT = FD->getType()->getAsFunctionType(); 735897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 736897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner 737897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 738897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 739897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 740897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 741897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner 742897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7433bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 744770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 745770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 746770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 747770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 7483bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 749770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 7502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7512f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 7522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian // Note! BlockDecl is typeless. Variadic diagnostics 7532f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian // will be issued by the caller. 7542f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 7552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 7562f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 757daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 758daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 759daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType(); 7602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7613bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 7623bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 7632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7642f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7652f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7662f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian else { 7672f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 768ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 7692f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7702f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 771770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 772fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 773ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 774770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 775770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 77688f1ba0f0439e31ab57ffc088aa91137cadee585Fariborz Jahanian d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 777770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 778770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 779026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 780026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 781026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 782026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 783026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 784026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 785026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 786026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // TODO: could also be applied to methods? 787026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 788026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (!Fn) { 789026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 791026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 792026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 793026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 7940b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 795026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 796026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 797026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 799545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 8056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 8066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8075dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8110b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) WeakAttr()); 8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 8166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 8176e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8186e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 8226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 8236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 8246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 8256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 8267297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor isDef = FD->getBody(S.Context); 827d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 828d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 8291c90f4dc686ab872013544664c797604a309c563Mike Stump return; 8306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else { 8316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8325dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8366e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 8376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 8386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), 8396e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 8406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 8416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar D->addAttr(::new (S.Context) WeakImportAttr()); 8456e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 8466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 847026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 849545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8537b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8542f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 855026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 8560b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLImportAttr()); 8572f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8582f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8592f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 860026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 8612f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 8622f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8635dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8672f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllimport attribute is ignored for inlined functions. 8682f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8692f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 8702f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8712f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8732f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8742f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // The attribute is also overridden by a subsequent declaration as dllexport. 8752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 8772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov nextAttr = nextAttr->getNext()) { 8782f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (nextAttr->getKind() == AttributeList::AT_dllexport) { 8792f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8802f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8812f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8822f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8832f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 884026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (D->getAttr<DLLExportAttr>()) { 8852f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8862f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8872f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8890b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLImportAttr()); 8906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 892026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 894545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8987b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8992f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 900026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 9010b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLExportAttr()); 9022f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9032f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9042f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 905026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 9062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 9072f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 9092f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9102f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9112f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 9122f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllexport attribute is ignored for inlined functions, 9132f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 9142f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 9152f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // FIXME: ... unless the -fkeep-inline-functions flag has been used. 9162f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 9172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 9200b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLExportAttr()); 9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 923026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 92417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 92517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 92617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 92717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 92817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 92917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 93017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 93117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 93217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar StringLiteral *SE = 93317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 93417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 93517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // FIXME 93617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 93717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 93817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 9390b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 9400b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 94117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 94217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 943803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 945545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9463c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute can be applied only to functions. 9517b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 9527b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9535dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9547b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9557b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9567b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9577b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 9587b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<FastCallAttr>()) { 9597b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 9607b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "fastcall"; 9617b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9627b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9637b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9640b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) StdCallAttr()); 9656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 967803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9687b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 969545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9703c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9737b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9747b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 9757b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9765dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9777b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9787b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9797b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9807b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 9817b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<StdCallAttr>()) { 9827b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 9837b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "stdcall"; 9847b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9857b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9867b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9870b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) FastCallAttr()); 9886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 990803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 992545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9970b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NoThrowAttr()); 9986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1000232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1001232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1002232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1004232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1005232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1006232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 10070b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) ConstAttr()); 1008232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1009232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1010232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1011232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1012232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1014232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1015232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1016232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 10170b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) PureAttr()); 1018232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1019232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1020f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 102189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // Match gcc which ignores cleanup attrs when compiling C++. 102289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (S.getLangOptions().CPlusPlus) 102389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 102489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 1025f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!Attr.getParameterName()) { 1026f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1027f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1028f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1029f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1030f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1031f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1032f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1033f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1035f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1036f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1037f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1038f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1039f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1040f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1041f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1042f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 104347b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 104447b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor Sema::LookupOrdinaryName); 1045f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 104689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1047f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1048f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1049f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1050f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1051f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1052f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 105389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1054f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1055f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1058f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 105989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1063f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 106489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 106589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 106689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 106789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1068d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 106989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), 107089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 107189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 107289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 107389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 107489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 10750b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) CleanupAttr(FD)); 1076f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1077f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 10786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 10796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1080803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1082545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1083fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 10843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1088545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 10893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 10906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1093620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1094fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10955dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 11023568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 11036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 11046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1105545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 1106545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 11076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 11096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 11106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 11116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 11126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 11136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 11166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 11176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 1118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 11196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 11216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 1122803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 1123803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 1124803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 1126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 1128085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 1133fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1134fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "format" << Attr.getParameterName()->getName(); 11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1142fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1148fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 11506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 11573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1159085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 1160085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1161fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1162fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1163085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1164085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 1165085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 11666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 11676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 1168803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 11696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 11706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1171fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1172fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 11736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 11766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1179fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1180fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1185545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1186803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1188fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 11906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 11946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 11953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1198803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 12043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1208fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1213fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 12143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12180b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 12206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 12230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 12246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1225545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 12263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 12276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12300c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 12310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1232bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 12330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 12340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 12350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 12360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 12370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 12380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 12405dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 12416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 12450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), 12460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 12470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 12490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 12500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl::field_iterator Field = RD->field_begin(S.Context), 12510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldEnd = RD->field_end(S.Context); 12520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 12530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 12540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1256bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 12570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 12580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 12590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (FirstType->isFloatingType() || FirstType->isVectorType()) { 12600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(FirstField->getLocation(), 12610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_floating); 12620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 12630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1264bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 12650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 12660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 12670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 12680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 12690c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 12700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 12710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 12720c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 12730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 12740c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 12750c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Field->getLocation(), 12760c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 12770c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 12780c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 12790c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(FirstField->getLocation(), 12800c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 12810c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1282bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1283bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1284bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 12856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12860c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD->addAttr(::new (S.Context) TransparentUnionAttr()); 12876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1291545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 12923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1295545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 12976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 12996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 13006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 13010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13040b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 13050b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 13066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1308803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1310545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 13113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1316545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 13176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 13187549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 13200b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlignedAttr(Align)); 13216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 132349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 132449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 132549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1327fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1328fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 132949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 133049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1331396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1332396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1333396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar << alignmentExpr->getSourceRange(); 1334396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1335396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1336396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 13370b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 13386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1339fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 13400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 1341065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 1342fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1343fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 1344fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1345fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 1346fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 13470b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1348fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1349fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1350fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1351fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 13533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1354fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1355fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1356fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1357fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1358fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 13590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1360fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1361fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1362fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1363fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1364fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1365fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1366fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1367fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1368fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1369fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1370fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1371fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1372fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1373fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 137473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1375fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1376fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 137773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 137873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 137973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 138073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 138173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 138273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 138373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 138473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 138573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 138673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 138773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 138873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 138973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 139073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 139173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 139273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1393fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1394fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1395fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1396fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1397fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 13980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1399fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 14000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1401fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1402fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1403fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 14040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1405fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1406fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1407fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1408fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1409fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1410fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1411fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1412fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1413fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1414fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1415fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1416fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1417fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 141873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 141973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 142073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 142173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 142273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isIntegralType()) 142373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 142473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 142573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 142673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 142773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 142873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 142973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 143073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 143173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1432f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Sync this with InitializePredefinedMacros; we need to match 1433f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // int8_t and friends, at least with glibc. 1434f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure 32/64-bit integers don't get defined to types of 1435f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // the wrong width on unusual platforms. 1436f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1437f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1438fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1439fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1440fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 14413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1442fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1443fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 14443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1445fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1446fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 144773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 144873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 144973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 145073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1451fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 14520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1453fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1455fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1456fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 145773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 145873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 145973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 146073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1461fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 14620b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1463fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14640b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1465fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1466fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1467fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 14680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1469fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 14700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1471fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14720b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1473fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1474fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1475fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 14760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1477fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 14780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1479fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1481fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 148273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 148373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 148473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1485f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1486f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1487f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1488f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1489f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1490f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 149173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1493fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 149473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 149573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1496fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1501fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1502fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1503fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 15040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1505d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1506d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1507d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1508d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1509d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1510d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1511e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 15125bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1513d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15145dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1515d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1516d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1517d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 15180b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NodebugAttr()); 1519d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1520d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 15215bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlssonstatic void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 15225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 15235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 15245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 15255bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 15265bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 15275bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1528c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 15295bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15305dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 15315bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 15325bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 15335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 15340b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NoinlineAttr()); 15355bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 15365bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1537cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 153826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 153926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 154026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 154126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 154226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 154326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1544c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1545c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 154626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15475dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 154826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 154926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 155026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1551c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!Fn->isInline()) { 1552cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1553c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1554c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1555c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner 15569f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor d->addAttr(::new (S.Context) GNUInlineAttr()); 155726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 155826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1559ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1560ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1561ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 156255d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1563ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1564ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 156555d3aaf9a537888734762170823daf750ea9036dEli Friedman 1566ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1567ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 15685dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1569ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1570ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 157155d3aaf9a537888734762170823daf750ea9036dEli Friedman 157255d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 157355d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 157455d3aaf9a537888734762170823daf750ea9036dEli Friedman if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 157555d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 157655d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 157755d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 157855d3aaf9a537888734762170823daf750ea9036dEli Friedman } 157955d3aaf9a537888734762170823daf750ea9036dEli Friedman 1580264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1581264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 158255d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 158355d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 158455d3aaf9a537888734762170823daf750ea9036dEli Friedman } 158555d3aaf9a537888734762170823daf750ea9036dEli Friedman 1586348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1587264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1588264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 158955d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 159055d3aaf9a537888734762170823daf750ea9036dEli Friedman } 159155d3aaf9a537888734762170823daf750ea9036dEli Friedman 159255d3aaf9a537888734762170823daf750ea9036dEli Friedman d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1593ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1594ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 15950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 1596b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 1597b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 1598b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1599b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1600b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 1601b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 16025dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 16035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek 16045dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 16055dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 16065dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 16075dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 16085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 16095dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16105dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 3 /* function or method */; 1611b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1612b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 1613b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 16145dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType())) { 16155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 16165dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName(); 16175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek return; 16185dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 16195dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek 1620b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 1621b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 1622b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 1623b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1624b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 1625b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1626b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1627b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 1628b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1629b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1630b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 1631b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 1632b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1633b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 16340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 16350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 16360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1637a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1638803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1639803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1640803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1641803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 16423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1643803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1644ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 1645ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian // Ignore these, these are type attributes, handled by ProcessTypeAttributes. 1646803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1647803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 16483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1649af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar case AttributeList::AT_always_inline: 1650af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 1651b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 1652b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek HandleAnalyzerNoReturnAttr (D, Attr, S); break; 16533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 16543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1655803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 16563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1657803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 16583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 16593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 16603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 16613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1662803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1663803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1664cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 16653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1666eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 16673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 16683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1669b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1670b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 1671b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 1672b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 1673b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 1674b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 16753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 167617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 16773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1678bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 167973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1680b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 16813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 16823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1683026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1684026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 16853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 16866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1687803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1688803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1689803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 16900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 16910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 16920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 1693f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1694fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 16959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1697232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1698232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1699f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1700d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 17015bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 170255d3aaf9a537888734762170823daf750ea9036dEli Friedman case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 170305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson case AttributeList::IgnoredAttribute: 17045e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 170505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 170605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 1707803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1708d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1709803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1710803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1713803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1714803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 1715803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1716803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 1717803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 1718803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1719803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1720803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 17220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 17230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 17240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 17250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 17260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 17270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 17280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 1729803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 17300744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 17310744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 17320744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 17330744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 17340744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 17350744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 17360744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 17370744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 17380744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 17390744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 17400744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 17410744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 1742