SemaDeclAttr.cpp revision e25ff83fb7eee9eeda89b6f2371bc33a37bf1028
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 27755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanianstatic const FunctionType *getFunctionType(Decl *d, bool blocksToo = true) { 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; 37bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 396217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<PointerType>()->getPointeeType(); 40755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian else if (blocksToo && Ty->isBlockPointerType()) 416217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = Ty->getAs<BlockPointerType>()->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) { 53755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian return getFunctionType(d, false) || 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 } 67d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return isa<BlockDecl>(d); 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 { 77d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian assert(isa<ObjCMethodDecl>(d) || isa<BlockDecl>(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(); 88d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 89d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getNumParams(); 9089951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 933568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 9489951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 9572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 96d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 97d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->getParamDecl(Idx)->getType(); 98bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 9989951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 1003568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1013568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1025b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanianstatic QualType getFunctionOrMethodResultType(Decl *d) { 1035b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (const FunctionType *FnTy = getFunctionType(d)) 1045b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<FunctionProtoType>(FnTy)->getResultType(); 1055b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return cast<ObjCMethodDecl>(d)->getResultType(); 1065b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 1075b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 1083568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 109d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 11072564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 1113568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 112d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(d)) 113d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian return BD->IsVariadic(); 114d66f22d9f8423579322a6dd16587ed52b0a58834Fariborz Jahanian else { 1153568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 1163568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 1173568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 1183568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 1196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 12014108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff const ObjCObjectPointerType *PT = T->getAsObjCObjectPointerType(); 121b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 123bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 124b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 1256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 127bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 129bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 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) { 1366217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const PointerType *PT = T->getAs<PointerType>(); 137085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 138085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 139085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 1406217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek const RecordType *RT = PT->getPointeeType()->getAs<RecordType>(); 141085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 142085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 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 159bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleExtVectorTypeAttr(Scope *scope, Decl *d, 1609cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor const AttributeList &Attr, 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 } 166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1689cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1699cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Expr *sizeExpr; 1709cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1719cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Special case where the argument is a template id. 1729cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getParameterName()) { 1739cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(), 1749cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor Attr.getParameterName(), 1759cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor false, 0, false).takeAs<Expr>(); 1769cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } else { 1779cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // check the attribute arguments. 1789cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (Attr.getNumArgs() != 1) { 1799cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1809cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor return; 1819cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor } 1829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1849cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor 1859cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Instantiate/Install the vector type, and let Sema build the type for us. 1869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // This will run the reguired checks. 1879cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc()); 1889cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor if (!T.isNull()) { 1899cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor tDecl->setUnderlyingType(T); 190bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1919cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor // Remember this typedef decl, we will need it later for diagnostics. 1929cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor S.ExtVectorDecls.push_back(tDecl); 1936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 197bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleVectorSizeAttribute - this attribute is only applicable to integral 198bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// and float scalars, although arrays, pointers, and function return values are 199bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// allowed in conjunction with this construct. Aggregates with this attribute 200bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// are invalid, even if they are of the same size as a corresponding scalar. 201bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// The raw attribute should contain precisely 1 argument, the vector size for 202bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// the variable, measured in bytes. If curType and rawAttr are well formed, 203bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// this routine will return a new vector type. 204803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 205065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 206065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 207065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 208065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 209065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 210065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 211fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 212fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 213065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 215bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 216065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 217545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 2183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 219065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 221545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 223803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 224fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 225fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << sizeExpr->getSourceRange(); 226065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 228bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // navigate to the base type - we need to provide for vector pointers, vector 229bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arrays, and functions returning vectors. 230b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 231b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2322db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType; 2332db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner return; 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 24682afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner // the base type must be integer or float, and can't already be a vector. 24782afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner if (CurType->isVectorType() || 24882afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner (!CurType->isIntegerType() && !CurType->isRealFloatingType())) { 249d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 250065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 252803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 254bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 255bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 258fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 259fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 260065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 263fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 264fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 265065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 267bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 268065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 269065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 270803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 271bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 272065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 273065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 274bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump else 275065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 278803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 280545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 284bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 2856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 28640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis TD->addAttr(::new (S.Context) PackedAttr(1)); 2876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 291803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 292fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 29308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 29540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis FD->addAttr(::new (S.Context) PackedAttr(1)); 2966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 30096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 30196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 30296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 3033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 30496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 30596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 306bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 30796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 30896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 309327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 31040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) IBOutletAttr()); 31196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 312327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 31396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 31496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 316bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // GCC ignores the nonnull attribute on K&R style function prototypes, so we 317bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ignore it as well 318d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 319fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3205dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 323bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 324d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 328bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 331bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 332bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 334f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 337fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 341bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 343bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 345fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 34630bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 348eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 349bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 350465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 353bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump QualType T = getFunctionOrMethodArgType(d, x); 354dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (!T->isAnyPointerType() && !T->isBlockPointerType()) { 355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 356fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 357fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 360bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 363bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 364bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // If no arguments were specified to __attribute__((nonnull)) then all pointer 365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // arguments have a nonnull attribute. 3667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 36746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 36846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 369dbfe99ef39163fd3574332673ee175c2bb6ef3caTed Kremenek if (T->isAnyPointerType() || T->isBlockPointerType()) 370d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 37146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 372bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3737fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3747fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3757fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3767fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 377eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3787fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3797fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3807fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3817fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 38240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NonNullAttr(start, size)); 383eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 384eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 385803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 387545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 391bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 392545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 395bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 397fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 401bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 404bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 406bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 40740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 4086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 410bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 411af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 412af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 413af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 4143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 415af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 416af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 4175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 418c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 4195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4205dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 4215bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 4225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 423bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 42440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlwaysInlineAttr()); 425af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 426af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 427b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 4285dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek Sema &S) { 4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 430545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 432b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 4336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 434d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 43519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { 43619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump ValueDecl *VD = dyn_cast<ValueDecl>(d); 43719c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump if (VD == 0 || !VD->getType()->isBlockPointerType()) { 43819c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 44019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump return false; 44119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump } 4426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 443bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 444b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 445b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 446b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 447b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 448bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 44940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoReturnAttr()); 450b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 451b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 452b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 453b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 454bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (HandleCommonNoReturnAttr(d, Attr, S)) 45540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 4566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 45873798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 45973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 46073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 46273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 46373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 464bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 465d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 466fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4675dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 46873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 46973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 470bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 47140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnusedAttr()); 47273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 47373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 474b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 475b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 477b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 478b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 479b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 480bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 481b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 482186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 483b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 484b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 485b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 486b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 487b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 4885dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 489b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 490b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 491bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 49240b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UsedAttr()); 493b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 494b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 4953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 498fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 499fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 501bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 508fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 5103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 514bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 515c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 516fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 52140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstructorAttr(priority)); 5223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 5263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 527fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 528fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 530bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 537fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 5393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 543bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5446782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 545fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 5465dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 5473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 55040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DestructorAttr(priority)); 5513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 553803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 555545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 5563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 559bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 56040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) DeprecatedAttr()); 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 563bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 564bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 565bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 566bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 567bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 568bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 569bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 57040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) UnavailableAttr()); 571bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 572bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 573803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 575545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 5763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 579bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 580545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 583bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 585fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 589bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 593bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 6026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 60308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 60740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) VisibilityAttr(type)); 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 6110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 6120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 6130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 6140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 6180db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 6190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 6200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 6210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 622bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 62340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCExceptionAttr()); 6240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 6250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 6260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 627fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 628fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 629fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 630fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6310db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 632fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 633fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 6346217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !T->getAs<PointerType>()->getPointeeType()->isRecordType()) { 635fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 636fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 637fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 638fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 63940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 640fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 641fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 642bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void 643f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 644f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 645f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 646f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 647f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 648f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 649f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 650f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 651f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 652f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 653f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 65440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) OverloadableAttr()); 655f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 656f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 658bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 659fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 663bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 668bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 6699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 67092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 673fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 6759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 677bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 67840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) BlocksAttr(type)); 6799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 6809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 684fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 685fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 687bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 688bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 690770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 691770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 694fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 699bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 701fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 702fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 703770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 707770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 708770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 709770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 710770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 712fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 7133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 717bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 719770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 720770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 721fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 722fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 724770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 726770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 727770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 728897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner const FunctionType *FT = FD->getType()->getAsFunctionType(); 729897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 731897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 732897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 733897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 734897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 735bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 736897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7373bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 738770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 740770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 741770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 7423bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0; 743770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 7442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (isa<BlockDecl>(d)) { 746bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Note! BlockDecl is typeless. Variadic diagnostics will be issued by the 747bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // caller. 7482f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian ; 7492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) { 7502f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian QualType Ty = V->getType(); 751daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) { 752bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d) 7536217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek : Ty->getAs<BlockPointerType>()->getPointeeType()->getAsFunctionType(); 7542f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian if (!cast<FunctionProtoType>(FT)->isVariadic()) { 7553bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian int m = Ty->isFunctionPointerType() ? 0 : 1; 7563bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m; 7572f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 7602f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian else { 7612f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 762ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 7632f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian return; 7642f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian } 765770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 766fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 767ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian << Attr.getName() << 6 /*function, method or block */; 768770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 769770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 77040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos)); 771770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 772770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 773026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 774026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 775026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 776026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 777026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 778026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 779026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 780026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // TODO: could also be applied to methods? 781026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 782026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (!Fn) { 783026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7845dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 785026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 786026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 787bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 78840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 789026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 790026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 791026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 793545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 798f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian /* weak only applies to non-static declarations */ 799f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian bool isStatic = false; 800f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 801f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = VD->getStorageClass() == VarDecl::Static; 802f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 803f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian isStatic = FD->getStorageClass() == FunctionDecl::Static; 804f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 805f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian if (isStatic) { 806f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_weak_static) << 807f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian dyn_cast<NamedDecl>(D)->getNameAsString(); 808f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian return; 809f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian } 810f23ecd91bf0205b776dfab2c5231e895019a7400Fariborz Jahanian 8116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 8126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 8136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8145dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8156e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8166e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 817bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 81840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakAttr()); 8196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8216e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 8236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 8246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 826bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 8276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 8296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 8306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 8316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 8326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 8336fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis isDef = FD->getBody(); 834d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) { 835d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian // We ignore weak import on properties and methods 8361c90f4dc686ab872013544664c797604a309c563Mike Stump return; 8376e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else { 8386e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8395dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8406e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8416e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8426e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 8436e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 8446e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 845bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 8466e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 8476e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 8486e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 8496e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 8506e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 85140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) WeakImportAttr()); 8526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 8536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 854026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 856545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8607b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8612f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 862026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 86340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLImportAttr()); 8642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 867026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 8682f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 8692f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8705dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 8712f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8732f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8742f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllimport attribute is ignored for inlined functions. 8752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 8772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8782f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8792f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8802f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8812f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // The attribute is also overridden by a subsequent declaration as dllexport. 8822f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8832f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 8842f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov nextAttr = nextAttr->getNext()) { 8852f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (nextAttr->getKind() == AttributeList::AT_dllexport) { 8862f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8872f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8892f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8902f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 89140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (D->getAttr<DLLExportAttr>()) { 8922f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8932f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8942f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8952f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 89640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLImportAttr()); 8976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 899026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 9006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 901545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9057b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 907026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 90840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLExportAttr()); 9092f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9102f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9112f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 912026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 9132f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 9142f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 2 /*variable and function*/; 9162f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 919bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Currently, the dllexport attribute is ignored for inlined functions, unless 920bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // the -fkeep-inline-functions flag has been used. Warning is emitted; 9212f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 9222f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // FIXME: ... unless the -fkeep-inline-functions flag has been used. 9232f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 9242f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 9252f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 9262f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 92740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) DLLExportAttr()); 9286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9306f3d838867538638b9bbf412028e8537ae12f3e5Nate Begemanstatic void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr, 9316f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Sema &S) { 9326f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman // Attribute has 3 arguments. 9336f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (Attr.getNumArgs() != 3) { 9346f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 9356f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 9366f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 9376f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 9386f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman unsigned WGSize[3]; 9396f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman for (unsigned i = 0; i < 3; ++i) { 9406f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman Expr *E = static_cast<Expr *>(Attr.getArg(i)); 9416f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman llvm::APSInt ArgNum(32); 9426f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman if (!E->isIntegerConstantExpr(ArgNum, S.Context)) { 9436f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 9446f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman << "reqd_work_group_size" << E->getSourceRange(); 9456f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman return; 9466f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 9476f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[i] = (unsigned) ArgNum.getZExtValue(); 9486f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman } 94940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1], 9506f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman WGSize[2])); 9516f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman} 9526f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 953026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 95417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 95517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 95617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 95717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 95817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 95917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 96017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 96117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 962bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump StringLiteral *SE = 96317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 96417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 96517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // FIXME 96617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 96717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 96817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 96940b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 9700b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 97117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 97217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 973803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9747b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 975545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9797b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9807b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute can be applied only to functions. 9817b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 9827b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 9835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 9847b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9857b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9867b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9877b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 98840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (d->getAttr<FastCallAttr>()) { 9897b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 9907b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "fastcall"; 9917b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9927b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9937b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 99440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) StdCallAttr()); 9956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 997803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9987b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 999545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10003c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10037b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10047b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 10057b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 10065dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 10077b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10097b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 10107b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 101140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (d->getAttr<StdCallAttr>()) { 10127b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 10137b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "stdcall"; 10147b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 10157b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 10167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 101740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FastCallAttr()); 10186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1020803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1022545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10233c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1026bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 102740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoThrowAttr()); 10286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1030232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1031232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1032232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1034232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1035232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1036bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 103740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) ConstAttr()); 1038232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1039232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1040232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1041232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 1042232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 10433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1044232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 1045232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 1046bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 104740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) PureAttr()); 1048232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 1049232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 1050f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 105189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // Match gcc which ignores cleanup attrs when compiling C++. 105289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (S.getLangOptions().CPlusPlus) 105389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 1054bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1055bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump if (!Attr.getParameterName()) { 1056f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1057f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1058f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1059bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1060f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 1061f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1062f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1063f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1064bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 1066bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1067f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 1068f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 1069f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1070f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1071bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1072f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 107347b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 107447b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor Sema::LookupOrdinaryName); 1075f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 107689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 1077f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1078f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1079f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1080bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1081f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1082f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 108389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1084f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1085f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1086f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1087f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1088f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 108989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1090f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1091f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1092f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1093bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 109489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 109589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 109689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 109789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1098d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { 1099bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 110089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 110189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 110289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 110389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 1104bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 110540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CleanupAttr(FD)); 1106f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1107f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1108bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format_arg((idx)))) attribute based on 1109bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1110bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11115b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Attr.getNumArgs() != 1) { 11125b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11135b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11145b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 11155b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 11165b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 11175b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << Attr.getName() << 0 /*function*/; 11185b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11195b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1120bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1121bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start with 1. 11225b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned NumArgs = getFunctionOrMethodNumArgs(d); 11235b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned FirstIdx = 1; 11245b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // checks for the 2nd argument 11255b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 11265b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian llvm::APSInt Idx(32); 11275b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 11285b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11295b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 11305b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11315b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1132bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11335b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 11345b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11355b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << "format" << 2 << IdxExpr->getSourceRange(); 11365b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 11375b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian } 1138bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11395b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian unsigned ArgIdx = Idx.getZExtValue() - 1; 1140bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11415b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // make sure the format string is really a string 11425b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 1143bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 11445b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian bool not_nsstring_type = !isNSStringType(Ty, S.Context); 11455b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (not_nsstring_type && 11465b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 11475b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 11486217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 11495b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 11505b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1151bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "a string type" : "an NSString") 11525b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 11535b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1154bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 11555b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian Ty = getFunctionOrMethodResultType(d); 11565b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian if (!isNSStringType(Ty, S.Context) && 11575b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian !isCFStringType(Ty, S.Context) && 11585b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian (!Ty->isPointerType() || 11596217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType())) { 11605b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian // FIXME: Should highlight the actual expression that has the wrong type. 11615b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian S.Diag(Attr.getLoc(), diag::err_format_attribute_result_not) 1162bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump << (not_nsstring_type ? "string type" : "NSString") 11635b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian << IdxExpr->getSourceRange(); 11645b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian return; 1165bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 1166bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 116740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue())); 11685b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian} 11695b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian 1170bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Handle __attribute__((format(type,idx,firstarg))) attributes based on 1171bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1172803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1174545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1175fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 11763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1180545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 11813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 11826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1185620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) { 1186fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 11875dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1191bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // FIXME: in C++ the implicit 'this' function parameter also counts. this is 1192bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // needed in order to be compatible with GCC the index must start in 1 and the 1193bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // limit is numargs+1 11943568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 11956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1197545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 1198545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 12016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 12046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 1210085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 1211bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 12136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 1214803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 1215803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 1216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 1218085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1219085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 1220085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 12226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1223bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 1225fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1226fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "format" << Attr.getParameterName()->getName(); 12276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1231545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1232803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1233803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1234fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 12366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1240fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 12413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 12466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 1247bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 12486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 12493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 12506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1251085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 1252085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1253fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1254fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1255085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1256085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 1257085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 1258390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: do we need to check if the type is NSString*? What are the 1259390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // semantics? 1260803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 1261390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1262fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1263fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 12646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1265bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump } 12666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 12676217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek !Ty->getAs<PointerType>()->getPointeeType()->isCharType()) { 1268390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Should highlight the actual expression that has the wrong type. 1269fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1270fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 12716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1275545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1276803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1277803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1278fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 12793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 12846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 12853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 12866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 12876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1288803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 12896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 12943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 12956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1297fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1298fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 12996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1303fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 13043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 13056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 130840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 13096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 13106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 13130b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 13146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1315545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 13163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 13176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Try to find the underlying union declaration. 13210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RecordDecl *RD = 0; 1322bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 13230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (TD && TD->getUnderlyingType()->isUnionType()) 13240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 13250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor else 13260c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor RD = dyn_cast<RecordDecl>(d); 13270c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 13280c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD || !RD->isUnion()) { 1329fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 13305dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 1 /*union*/; 13316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 13336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (!RD->isDefinition()) { 1335bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), 13360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_not_definition); 13370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 13380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 13390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor 134017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis RecordDecl::field_iterator Field = RD->field_begin(), 134117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 13420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (Field == FieldEnd) { 13430c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields); 13440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 13450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1346bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 13470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor FieldDecl *FirstField = *Field; 13480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FirstType = FirstField->getType(); 13490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (FirstType->isFloatingType() || FirstType->isVectorType()) { 1350bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 13510c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_floating); 13520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor return; 13530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor } 1354bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 13550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstSize = S.Context.getTypeSize(FirstType); 13560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor uint64_t FirstAlign = S.Context.getTypeAlign(FirstType); 13570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor for (; Field != FieldEnd; ++Field) { 13580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor QualType FieldType = Field->getType(); 13590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor if (S.Context.getTypeSize(FieldType) != FirstSize || 13600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor S.Context.getTypeAlign(FieldType) != FirstAlign) { 13610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor // Warn if we drop the attribute. 13620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor bool isSize = S.Context.getTypeSize(FieldType) != FirstSize; 1363bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType) 13640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor : S.Context.getTypeAlign(FieldType); 1365bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Field->getLocation(), 13660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::warn_transparent_union_attribute_field_size_align) 13670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << Field->getDeclName() << FieldBits; 13680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor unsigned FirstBits = isSize? FirstSize : FirstAlign; 1369bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(FirstField->getLocation(), 13700c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor diag::note_transparent_union_first_field_size_align) 13710c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor << isSize << FirstBits; 1372bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1373bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1374bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 13756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 137640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis RD->addAttr(::new (S.Context) TransparentUnionAttr()); 13776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 13790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1381545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 13823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 13836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1385545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 13866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 1387bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 13886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 13896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 13906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 13910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 13926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 13936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 139440b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 13950b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 13966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 13976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 13996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1400545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 14013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 14026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 14046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 14056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1406545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 14076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 14087549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 14096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 141040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Align)); 14116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 14126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1413bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 141449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 141549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1416803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1417fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1418fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 141949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 142049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1421396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1422bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1423396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar << alignmentExpr->getSourceRange(); 1424396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1425396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1426396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 142740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 14286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1429fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1430bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HandleModeAttr - This attribute modifies the width of a decl with primitive 1431bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type. 1432fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1433bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// Despite what would be logical, the mode attribute is a decl attribute, not a 1434bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be 1435bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump/// HImode, not an intermediate pointer. 14360b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1437fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1438fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1439fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1440fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1441fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 14423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1443fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1444fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1445fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1446fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1447fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 14480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1449fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1450fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1451fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1452fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1453fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1454fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1455fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1456fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1457fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1458fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1459fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1460fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1461fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1462fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 146373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1464fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1465fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 146673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 146773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 146873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 146973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 147073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 147173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 147273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 147373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 147473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 147573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 147673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 147773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 147873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 147973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 148073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 148173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1482fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1484fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 14870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1488fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 14890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1491fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1492fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 14930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1494fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1495fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1496fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1497fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1498fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1499fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1500fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1501fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1502fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1503fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1504fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1505fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1506fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 150773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 150873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 150973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 151073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 151173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isIntegralType()) 151273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 151373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 151473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 151573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 151673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 151773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 151873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 151973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 152073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1521390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t 1522390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // and friends, at least with glibc. 1523390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong 1524390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump // width on unusual platforms. 1525f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1526f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1527fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1528fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1529fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 15303c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1531fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1532fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 15333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1534fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1535fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 153673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 153773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 153873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 153973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1540fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 15410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1542fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 15430b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1544fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1545fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 154673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 154773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 154873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 154973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1550fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 15510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1552fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 15530b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1554fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1555fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1556fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 15570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1558fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 15590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1560fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 15610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1562fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1563fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1564fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 15650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1566fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 15670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1568fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 15690b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1570fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 157173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 157273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 157373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1574f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1575f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1576f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1577f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1578f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1579f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 158073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1581fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1582fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 158373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 158473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1585fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1586fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1587fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1588fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1589fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1590fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1591fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1592fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 15930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1594d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1595d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1596d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1597d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1598d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1599d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1600e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 16015bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1602d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1604d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1605d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1606bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 160740b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NodebugAttr()); 1608d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1609d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 16105bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlssonstatic void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 16115bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 16125bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 16135bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 16145bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 16155bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1616bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1617c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 16185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16195dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 16205bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 16215bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 1622bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 162340b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NoinlineAttr()); 16245bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 16255bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1626cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 162726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 162826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 162926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 163026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 163126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1632bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1633c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1634c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 163526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16365dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 163726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 163826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 1639bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1640c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!Fn->isInline()) { 1641cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1642c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1643c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1644bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 164540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) GNUInlineAttr()); 164626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 164726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1648ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1649ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1650ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 165155d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1652ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1653ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 165455d3aaf9a537888734762170823daf750ea9036dEli Friedman 1655ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1656ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16575dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 0 /*function*/; 1658ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1659ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 166055d3aaf9a537888734762170823daf750ea9036dEli Friedman 166155d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 166255d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 166355d3aaf9a537888734762170823daf750ea9036dEli Friedman if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 166455d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 166555d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 166655d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 166755d3aaf9a537888734762170823daf750ea9036dEli Friedman } 166855d3aaf9a537888734762170823daf750ea9036dEli Friedman 1669264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1670264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 167155d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 167255d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 167355d3aaf9a537888734762170823daf750ea9036dEli Friedman } 167455d3aaf9a537888734762170823daf750ea9036dEli Friedman 1675348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1676264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1677264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 167855d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 167955d3aaf9a537888734762170823daf750ea9036dEli Friedman } 168055d3aaf9a537888734762170823daf750ea9036dEli Friedman 168140b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1682ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1683ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 16840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 1685b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers. 1686b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 1687b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1688b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, 1689b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek Sema &S) { 1690b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 16915dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek QualType RetTy; 1692bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 16935dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) 16945dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = MD->getResultType(); 16955dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) 16965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek RetTy = FD->getResultType(); 16975dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek else { 16985dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 16995dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName() << 3 /* function or method */; 1700b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1701b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek } 1702bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 17036217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAs<PointerType>() 170414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff || RetTy->getAsObjCObjectPointerType())) { 17055dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type) 17065dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek << Attr.getName(); 1707bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump return; 17085dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek } 1709bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 1710b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek switch (Attr.getKind()) { 1711b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek default: 1712b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek assert(0 && "invalid ownership attribute"); 1713b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1714b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 171540b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) CFReturnsRetainedAttr()); 1716b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1717b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 171840b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis d->addAttr(::new (S.Context) NSReturnsRetainedAttr()); 1719b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek return; 1720b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek }; 1721b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek} 1722b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1723b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===// 17240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 17250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 17260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1727a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1728803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1729803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1730bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stumpstatic void ProcessDeclAttribute(Scope *scope, Decl *D, 1731bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump const AttributeList &Attr, Sema &S) { 1732290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman if (Attr.isDeclspecAttribute()) 1733290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman // FIXME: Try to deal with __declspec attributes! 1734290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman return; 1735803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 17363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1737803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1738ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 1739bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // Ignore these, these are type attributes, handled by 1740bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump // ProcessTypeAttributes. 1741803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1742803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 17433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1744bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::AT_always_inline: 1745af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 1746b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 1747bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump HandleAnalyzerNoReturnAttr (D, Attr, S); break; 17483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 17493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1750803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 17513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1752803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 17533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 17543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 17559cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor HandleExtVectorTypeAttr(scope, D, Attr, S); 17563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1757803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1758803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 17595b160927672440076aa53c31d84149f70fd8d40eFariborz Jahanian case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break; 1760cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 17613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1762eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 17633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 17643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 1765b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 1766b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek // Checker-specific. 1767b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_ns_returns_retained: 1768b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek case AttributeList::AT_cf_returns_retained: 1769b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek HandleNSReturnsRetainedAttr(D, Attr, S); break; 1770b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek 17716f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman case AttributeList::AT_reqd_wg_size: 17726f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman HandleReqdWorkGroupSize(D, Attr, S); break; 17736f3d838867538638b9bbf412028e8537ae12f3e5Nate Begeman 17743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 177517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 17763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1777bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 177873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1779b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 17803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 17813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1782026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1783026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 17843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 17856e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1786803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1787803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1788803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 17890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 17900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 17910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 1792f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1793fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 17949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1795770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1796232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1797232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1798f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1799d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 18005bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 180155d3aaf9a537888734762170823daf750ea9036dEli Friedman case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 1802bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump case AttributeList::IgnoredAttribute: 18035e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner case AttributeList::AT_no_instrument_function: // Interacts with -pg. 180405f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 180505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 1806803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1807d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1809803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1810803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1811803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1812803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1813803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 18149cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AttrList) { 1815803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 18169cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttribute(S, D, *AttrList, *this); 1817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1818803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1819803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1820803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1821e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclClonePragmaWeak - clone existing decl (maybe definition), 1822e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// #pragma weak needs a non-definition decl and source may not have one 1823e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynnstatic NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) 1824e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn{ 1825e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = 0; 1826e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { 1827e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(), 1828e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getLocation(), DeclarationName(II), 1829e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn FD->getType()); 1830e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) { 1831e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(), 1832e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getLocation(), II, 1833e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn VD->getType(), VD->getStorageClass()); 1834e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1835e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn return NewD; 1836e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1837e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 1838e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak 1839e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn/// applied to it, possibly with an alias. 1840e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynnvoid Sema::DeclApplyPragmaWeak(NamedDecl *ND, WeakInfo &W) { 1841e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND)); 1842e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (!W.getUsed()) { // only do this once 1843e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn W.setUsed(true); 1844e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...)) 1845e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn IdentifierInfo *NDId = ND->getIdentifier(); 1846e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias()); 1847e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD->addAttr(::new (Context) AliasAttr(NDId->getName())); 1848e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn NewD->addAttr(::new (Context) WeakAttr()); 1849e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn ND->getDeclContext()->addDecl(NewD); 1850e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } else { // just add weak to existing 1851e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn ND->addAttr(::new (Context) WeakAttr()); 1852e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1853e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1854e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn} 1855e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 18560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 18570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 18580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 18599cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregorvoid Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { 1860e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Handle #pragma weak 1861e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 1862e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (ND->hasLinkage()) { 1863e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier()); 1864e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn if (W != WeakInfo()) { 1865e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn // Declaration referenced by #pragma weak before it was declared 1866e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn DeclApplyPragmaWeak(ND, W); 1867e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn WeakUndeclaredIdentifiers[ND->getIdentifier()] = W; 1868e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1869e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1870e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn } 1871e25ff83fb7eee9eeda89b6f2371bc33a37bf1028Ryan Flynn 18720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 18730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 18749cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1875bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 18770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 18780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 18790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 18800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 18810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 18829cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 1883bf91650557d9afa08e3d311a9c0a10d73c62cbfcMike Stump 18840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 18850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 18869cdda0cf8528e3d595be9bfa002f0450074beb4dDouglas Gregor ProcessDeclAttributeList(S, D, Attrs); 18870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 1888