SemaDeclAttr.cpp revision cf2a7211b4785068c7efa836baab90b198a4d2a6
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===// 26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// The LLVM Compiler Infrastructure 46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source 66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details. 76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file implements decl-related attribute processing. 116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// 126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===// 136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h" 156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h" 16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h" 17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h" 18fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 1912bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 206e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h> 216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 27d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic const FunctionType *getFunctionType(Decl *d) { 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = Ty->getAsPointerType()->getPointeeType(); 40d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 41d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return Ty->getAsFunctionType(); 426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 443568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 453568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 47d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function 48d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) { 51d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return getFunctionType(d) || isa<ObjCMethodDecl>(d); 52d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 54d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 55d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 56d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod. 57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) { 58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 5972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return isa<FunctionProtoType>(FnTy); 60d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } else { 61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar assert(isa<ObjCMethodDecl>(d)); 62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 63d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 643568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 66d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 693568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) { 7089951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 7172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getNumArgs(); 7289951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_size(); 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 7689951a86b594513c2a013532ed45d197413b1087Chris Lattner if (const FunctionType *FnTy = getFunctionType(d)) 7772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor return cast<FunctionProtoType>(FnTy)->getArgType(Idx); 7889951a86b594513c2a013532ed45d197413b1087Chris Lattner 7989951a86b594513c2a013532ed45d197413b1087Chris Lattner return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); 803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 8472564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy); 853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 92b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 93b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 96b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 1016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 107085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 108085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const PointerType *PT = T->getAsPointerType(); 109085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 110085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 111085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 114085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 119085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 120085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 121085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 122085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 123e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 124e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 125e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 126e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 131803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 132803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 133545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 134545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 135803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 136545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 141545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 1423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 145545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 148fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 149fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "ext_vector_type" << sizeExpr->getSourceRange(); 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 154b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 155d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType; 1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 164fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 168803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 173065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 174065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 175065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 176065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 177065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 179065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 182803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 184065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 189fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 190fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 195545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 1963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 199545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 201803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 202fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 203fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << sizeExpr->getSourceRange(); 204065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 208b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 209b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 224b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 225d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 226065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 228803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 234fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 235fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 236065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 240fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 241065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 243065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 244065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 245065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 246803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 247065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 248065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 249065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 250065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 251065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 254803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 256545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 2620b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner TD->addAttr(::new (S.Context) PackedAttr(1)); 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 267803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 268fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 26908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 2710b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner FD->addAttr(::new (S.Context) PackedAttr(1)); 2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 27796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 27896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 28096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 28196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 28496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 285327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) 2860b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) IBOutletAttr()); 28796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 288327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet); 28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 294d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 295fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 296026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "nonnull" << 0 /*function*/; 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 300d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 301eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 303eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 304eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 305eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 310f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 313fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 314fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 321fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 32230bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 325465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 326465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 32946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, x); 33046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (!T->isPointerType() && !T->isBlockPointerType()) { 331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 333fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3347fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 3407fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // If no arguments were specified to __attribute__((nonnull)) then all 3417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // pointer arguments have a nonnull attribute. 3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 34346bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 34446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 34546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (T->isPointerType() || T->isBlockPointerType()) 346d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 34746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 353eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3557fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3580b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NonNullAttr(start, size)); 359eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 360eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 361803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 363545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 368545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 373fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3830b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 386af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 387af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 388af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 389af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 3903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 391af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 392af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 3935bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 394c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 3955bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 3965bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson << "always_inline" << 0 /*function*/; 3975bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 3985bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 399af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 4000b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlwaysInlineAttr()); 401af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 402af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 403b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, 404b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S, const char *attrName) { 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 406545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 408b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 410d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 411d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d)) { 412fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 413b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek << attrName << 0 /*function*/; 414b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return false; 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 417b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek return true; 418b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 419b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 420b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 421b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek if (HandleCommonNoReturnAttr(d, Attr, S, "noreturn")) 422b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek d->addAttr(::new (S.Context) NoReturnAttr()); 423b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek} 424b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek 425b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, 426b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek Sema &S) { 427b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek if (HandleCommonNoReturnAttr(d, Attr, S, "analyzer_noreturn")) 428b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); 4296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 43373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 43573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 43673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 43773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 438d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 439fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 440026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "unused" << 2 /*variable and function*/; 44173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 44273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 44373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 4440b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UnusedAttr()); 44573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 44673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 447b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 448b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar // check the attribute arguments. 449b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (Attr.getNumArgs() != 0) { 450b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 451b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 452b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 453b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 454b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar if (const VarDecl *VD = dyn_cast<VarDecl>(d)) { 455186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar if (VD->hasLocalStorage() || VD->hasExternalStorage()) { 456b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used"; 457b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 458b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 459b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } else if (!isFunctionOrMethod(d)) { 460b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 461026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "used" << 2 /*variable and function*/; 462b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar return; 463b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar } 464b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 4650b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UsedAttr()); 466b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar} 467b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar 4683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 472fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 481fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 4823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 488c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 489fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 490026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "constructor" << 0 /*function*/; 4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4940b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) ConstructorAttr(priority)); 4953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 500fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 501fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 5063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 5073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 5083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 5093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 510fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 5113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 5123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 5153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5176782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 518fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 519026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "destructor" << 0 /*function*/; 5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 5213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 5223068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 5230b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) DestructorAttr(priority)); 5243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 528545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 5293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5330b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) DeprecatedAttr()); 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 536bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 537bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 538bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 539bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 540bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 541bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 542bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 5430b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) UnavailableAttr()); 544bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 545bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 546803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 548545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 5493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 5506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 553545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 558fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 5686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 5716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 5756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 57608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5800b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) VisibilityAttr(type)); 5816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5830db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr, 5840db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner Sema &S) { 5850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (Attr.getNumArgs() != 0) { 5860db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 5870db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 5880db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 5890db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 5900db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D); 5910db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (OCI == 0) { 5920db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface); 5930db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner return; 5940db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner } 5950db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 5960b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) ObjCExceptionAttr()); 5970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner} 5980db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner 5990db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) { 600fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 601fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 602fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 603fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) { 605fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 606fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 607fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian !T->getAsPointerType()->getPointeeType()->isRecordType()) { 608fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 609fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 610fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 611fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 6120b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) ObjCNSObjectAttr()); 613fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 614fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 615f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void 616f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 617f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 618f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 619f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 620f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 621f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 622f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 623f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 624f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 625f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 626f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6270b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) OverloadableAttr()); 628f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 629f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6319eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (!Attr.getParameterName()) { 632fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6369eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6379eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6399eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6409eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6419eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6429eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 64392e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6449eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6459eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 646fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 6489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6509eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6510b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) BlocksAttr(type)); 6529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 6539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 654770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 655770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 656770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 657fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 658fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 661770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 662770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 663770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 664770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 665770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 666770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 667fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 669770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 670770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 671770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 672770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 673770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 674fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 675fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 676770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 679770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 680770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 684770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 685fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6863c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 690770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 691770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 694fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 695fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 701897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner const FunctionType *FT = FD->getType()->getAsFunctionType(); 702897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner assert(FT && "FunctionDecl has non-function type?"); 703897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner 704897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (isa<FunctionNoProtoType>(FT)) { 705897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments); 706897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner return; 707897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner } 708897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner 709897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner if (!cast<FunctionProtoType>(FT)->isVariadic()) { 710770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 712770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 713770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 717770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 719fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 720026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "sentinel" << 3 /*function or method*/; 721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 724770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: Actually create the attribute. 725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 726770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 727026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) { 728026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // check the attribute arguments. 729026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (Attr.getNumArgs() != 0) { 730026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 731026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 732026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 733026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 734026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner // TODO: could also be applied to methods? 735026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(D); 736026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (!Fn) { 737026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 738026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "warn_unused_result" << 0 /*function*/; 739026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner return; 740026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner } 741026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 7420b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner Fn->addAttr(::new (S.Context) WarnUnusedResultAttr()); 743026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner} 744026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner 745026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 747545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7516e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 7526e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // TODO: could also be applied to methods? 7536e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) { 7546e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7556e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak" << 2 /*variable and function*/; 7566e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 7576e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 7586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7590b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) WeakAttr()); 7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7626e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7636e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // check the attribute arguments. 7646e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (Attr.getNumArgs() != 0) { 7656e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7666e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 7676e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 7686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 7696e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // weak_import only applies to variable & function declarations. 7706e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar bool isDef = false; 7716e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 7726e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar isDef = (!VD->hasExternalStorage() || VD->getInit()); 7736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 7747297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor isDef = FD->getBody(S.Context); 775862a2c55c45ffcb0fa3dfa6b8d3dee8d30e305cfMike Stump } else if (isa<ObjCPropertyDecl>(D)) { 776862a2c55c45ffcb0fa3dfa6b8d3dee8d30e305cfMike Stump // We ignore weak import on properties 7771c90f4dc686ab872013544664c797604a309c563Mike Stump return; 7786e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } else { 7796e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7806e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 7816e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 7826e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 7836e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 7846e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar // Merge should handle any subsequent violations. 7856e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar if (isDef) { 7866e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar S.Diag(Attr.getLoc(), 7876e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar diag::warn_attribute_weak_import_invalid_on_definition) 7886e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar << "weak_import" << 2 /*variable and function*/; 7896e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar return; 7906e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar } 7916e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 7926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar D->addAttr(::new (S.Context) WeakImportAttr()); 7936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar} 7946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar 795026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 797545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8017b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8022f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 803026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 8040b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLImportAttr()); 8052f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8072f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 808026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 8092f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 8102f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 811026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "dllimport" << 2 /*variable and function*/; 8122f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8132f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8142f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8152f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllimport attribute is ignored for inlined functions. 8162f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 8182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8202f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8212f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8222f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // The attribute is also overridden by a subsequent declaration as dllexport. 8232f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 8242f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 8252f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov nextAttr = nextAttr->getNext()) { 8262f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (nextAttr->getKind() == AttributeList::AT_dllexport) { 8272f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8282f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8292f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8312f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 832026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (D->getAttr<DLLExportAttr>()) { 8332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 8342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8362f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8370b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLImportAttr()); 8386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 840026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) { 8416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 842545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8433c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 848026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner if (isa<VarDecl>(D)) { 8490b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLExportAttr()); 8502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8512f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8522f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 853026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner FunctionDecl *FD = dyn_cast<FunctionDecl>(D); 8542f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 8552f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 856026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "dllexport" << 2 /*variable and function*/; 8572f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8582f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8592f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8602f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllexport attribute is ignored for inlined functions, 8612f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 8622f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 8632f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // FIXME: ... unless the -fkeep-inline-functions flag has been used. 8642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 8652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 8662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 8672f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 8680b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) DLLExportAttr()); 8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 871026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { 87217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 87317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 87417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 87517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 87617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 87717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 87817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 87917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 88017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar StringLiteral *SE = 88117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 88217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 88317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // FIXME 88417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 88517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 88617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 8870b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(), 8880b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 88917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 89017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 891803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8927b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 893545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8977b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8987b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute can be applied only to functions. 8997b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 9007b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 901026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "stdcall" << 0 /*function*/; 9027b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9037b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9047b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9057b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 9067b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<FastCallAttr>()) { 9077b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 9087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "fastcall"; 9097b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9107b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9117b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9120b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) StdCallAttr()); 9136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 915803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 917545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9183c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9217b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9227b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 9237b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 924026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "fastcall" << 0 /*function*/; 9257b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9267b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9277b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9287b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 9297b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<StdCallAttr>()) { 9307b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 9317b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "stdcall"; 9327b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 9337b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 9347b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 9350b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) FastCallAttr()); 9366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 938803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 940545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9413c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 9426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9450b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NoThrowAttr()); 9466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 948232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 949232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 950232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 9513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 952232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 953232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 954232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 9550b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) ConstAttr()); 956232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 957232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 958232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 959232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 960232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 9613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 962232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 963232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 964232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 9650b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) PureAttr()); 966232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 967232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 968f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 96989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // Match gcc which ignores cleanup attrs when compiling C++. 97089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (S.getLangOptions().CPlusPlus) 97189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 97289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 973f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!Attr.getParameterName()) { 974f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 975f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 976f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 977f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 978f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 979f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 980f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 981f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 982f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 983f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 984f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 985f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 986f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 987f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 988f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 989f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 990f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 99147b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 99247b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor Sema::LookupOrdinaryName); 993f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 99489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 995f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 996f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 997f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 998f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 999f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 1000f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 100189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 1002f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1003f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1004f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1005f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 1006f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 100789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 1008f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 1009f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 1010f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 1011f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 101289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 101389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 101489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 101589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 1016b90052a8cc4745126f7bb2e6573f07e22f24b840Anders Carlsson if (S.CheckAssignmentConstraints(Ty, ParamTy) != Sema::Compatible) { 101789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), 101889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 101989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 102089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 102189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 102289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 10230b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) CleanupAttr(FD)); 1024f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 1025f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 10266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 10276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 1028803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 10296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1030545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 1031fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 10323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 10336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1036545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 10373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1041d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 1042fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1043026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "format" << 0 /*function*/; 10446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 10486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 10496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 10503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 10516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 10526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1053545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 1054545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 10576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 10596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 10606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 10616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 10646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 10656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 1066085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 10676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 10696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 1070803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 1071803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 1072803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 10736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 1074085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 1075085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 1076085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 10776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 10786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 1081fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 1082fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "format" << Attr.getParameterName()->getName(); 10836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1087545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1088803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1089803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1090fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1096fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 10973c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 10986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 11036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 11053568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 11066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1107085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 1108085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1109fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1110fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1111085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 1113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 11146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 11156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 1116803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 11176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 11186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1119fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1120fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 11216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 11246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 11266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1127fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1128fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1133545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1135803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1136fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 11373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 11386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 11433568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1146803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 11476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 11523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 11536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1155fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1156fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 11606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1161fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 11623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 11636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11660b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen), 11676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 11710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 11726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1173545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 11743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 11756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1178bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This shouldn't be restricted to typedefs 1179bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1180bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!TD || !TD->getUnderlyingType()->isUnionType()) { 1181fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1182026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "transparent_union" << 1 /*union*/; 11836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1186bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1187bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 1188bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: Should we do a check for RD->isDefinition()? 1189bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 1190bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This isn't supposed to be restricted to pointers, but otherwise 1191bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // we might silently generate incorrect code; see following code 11926ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor for (RecordDecl::field_iterator Field = RD->field_begin(S.Context), 11936ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor FieldEnd = RD->field_end(S.Context); 119444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor Field != FieldEnd; ++Field) { 119544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor if (!Field->getType()->isPointerType()) { 1196bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 1197bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1198bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1199bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1201bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This is a complete hack; we should be properly propagating 1202bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // transparent_union through Sema. That said, this is close enough to 1203bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // correctly compile all the common cases of transparent_union without 1204bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // errors or warnings 1205bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman QualType NewTy = S.Context.VoidPtrTy; 1206bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman NewTy.addConst(); 1207bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TD->setUnderlyingType(NewTy); 12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12100b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1212545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 12133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1216545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 12176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 12186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 12206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 12216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 12220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 12236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12250b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), 12260b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner SE->getByteLength()))); 12276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1229803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1231545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 12323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 12336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 12356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 12366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1237545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 12386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 12397549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar // (For now we just use 128 bits which is the maximum on X86). 12406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 12410b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlignedAttr(Align)); 12426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 12436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 124449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 124549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 124649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1247803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1248fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1249fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 125049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 125149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 1252396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { 1253396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) 1254396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar << alignmentExpr->getSourceRange(); 1255396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar return; 1256396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar } 1257396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar 12580b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); 12596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1260fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 12610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 1262065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 1263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1264fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 1265fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1266fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 1267fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 12680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1269fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1270fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1271fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1272fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1273fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 12743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1275fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1276fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1277fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1279fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 12800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1281fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1282fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1283fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1285fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1286fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1287fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1288fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1289fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1290fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1291fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1293fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1294fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 129573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman bool ComplexMode = false; 1296fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1297fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 129873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman switch (Str[0]) { 129973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'Q': DestWidth = 8; break; 130073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'H': DestWidth = 16; break; 130173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'S': DestWidth = 32; break; 130273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'D': DestWidth = 64; break; 130373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'X': DestWidth = 96; break; 130473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 'T': DestWidth = 128; break; 130573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 130673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (Str[1] == 'F') { 130773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 130873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] == 'C') { 130973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman IntegerMode = false; 131073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman ComplexMode = true; 131173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (Str[1] != 'I') { 131273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman DestWidth = 0; 131373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1314fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1315fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1316fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1317fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1318fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 13190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1320fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 13210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1322fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1323fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1324fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 13250b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1326fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1327fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1328fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1329fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1330fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1331fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1332fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1333fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1334fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1335fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1336fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1337fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1338fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 133973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 134073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType()) 134173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 134273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman else if (IntegerMode) { 134373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isIntegralType()) 134473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 134573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else if (ComplexMode) { 134673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isComplexType()) 134773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 134873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } else { 134973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!OldTy->isFloatingType()) 135073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 135173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 135273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman 1353f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Sync this with InitializePredefinedMacros; we need to match 1354f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // int8_t and friends, at least with glibc. 1355f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure 32/64-bit integers don't get defined to types of 1356f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // the wrong width on unusual platforms. 1357f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1358f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1359fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1360fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1361fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 13623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1363fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1364fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 13653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1366fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1367fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 136873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 136973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 137073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 137173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1372fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 13730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1374fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 13750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1376fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1377fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 137873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (!IntegerMode) { 137973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 138073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman return; 138173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman } 1382fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 13830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1384fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 13850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1386fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1387fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1388fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 13890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1390fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 13910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1392fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 13930b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1394fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1395fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1396fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 13970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1398fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 13990b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1400fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 14010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1402fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 140373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman case 96: 140473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.LongDoubleTy; 140573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1406f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1407f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1408f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1409f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1410f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1411f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 141273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman break; 1413fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1414fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 141573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman if (ComplexMode) { 141673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman NewTy = S.Context.getComplexType(NewTy); 1417fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1418fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1419fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1420fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1421fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1422fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1423fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1424fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 14250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1426d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1427d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson // check the attribute arguments. 1428d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson if (Attr.getNumArgs() > 0) { 1429d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1430d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1431d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1432e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson 14335bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (!isFunctionOrMethod(d)) { 1434d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1435026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner << "nodebug" << 0 /*function*/; 1436d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson return; 1437d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson } 1438d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 14390b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NodebugAttr()); 1440d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson} 1441d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson 14425bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlssonstatic void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 14435bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson // check the attribute arguments. 14445bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson if (Attr.getNumArgs() != 0) { 14455bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 14465bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 14475bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 14485bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1449c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!isa<FunctionDecl>(d)) { 14505bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 14515bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson << "noinline" << 0 /*function*/; 14525bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson return; 14535bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson } 14545bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 14550b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner d->addAttr(::new (S.Context) NoinlineAttr()); 14565bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson} 14575bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson 1458cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { 145926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner // check the attribute arguments. 146026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner if (Attr.getNumArgs() != 0) { 146126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 146226e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 146326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 146426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1465c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 1466c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn == 0) { 146726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1468cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner << "gnu_inline" << 0 /*function*/; 146926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner return; 147026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner } 147126e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1472c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (!Fn->isInline()) { 1473cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); 1474c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1475c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1476c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner 1477c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner if (Fn->getStorageClass() == FunctionDecl::Extern) { 1478cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_extern_inline); 1479c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner return; 1480c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner } 1481c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner 1482cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner d->addAttr(::new (S.Context) GNUInlineAttr()); 148326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner} 148426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner 1485ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { 1486ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian // check the attribute arguments. 1487ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (Attr.getNumArgs() != 1) { 148855d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1489ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1490ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 149155d3aaf9a537888734762170823daf750ea9036dEli Friedman 1492ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian if (!isFunctionOrMethod(d)) { 1493ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1494ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian << "regparm" << 0 /*function*/; 1495ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian return; 1496ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian } 149755d3aaf9a537888734762170823daf750ea9036dEli Friedman 149855d3aaf9a537888734762170823daf750ea9036dEli Friedman Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); 149955d3aaf9a537888734762170823daf750ea9036dEli Friedman llvm::APSInt NumParams(32); 150055d3aaf9a537888734762170823daf750ea9036dEli Friedman if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { 150155d3aaf9a537888734762170823daf750ea9036dEli Friedman S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 150255d3aaf9a537888734762170823daf750ea9036dEli Friedman << "regparm" << NumParamsExpr->getSourceRange(); 150355d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 150455d3aaf9a537888734762170823daf750ea9036dEli Friedman } 150555d3aaf9a537888734762170823daf750ea9036dEli Friedman 1506264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov if (S.Context.Target.getRegParmMax() == 0) { 1507264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform) 150855d3aaf9a537888734762170823daf750ea9036dEli Friedman << NumParamsExpr->getSourceRange(); 150955d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 151055d3aaf9a537888734762170823daf750ea9036dEli Friedman } 151155d3aaf9a537888734762170823daf750ea9036dEli Friedman 1512348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) { 1513264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number) 1514264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange(); 151555d3aaf9a537888734762170823daf750ea9036dEli Friedman return; 151655d3aaf9a537888734762170823daf750ea9036dEli Friedman } 151755d3aaf9a537888734762170823daf750ea9036dEli Friedman 151855d3aaf9a537888734762170823daf750ea9036dEli Friedman d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); 1519ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian} 1520ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian 15210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 15220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 15230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 15240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1525a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1526803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1527803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1528803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1529803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 15303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1531803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1532ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian case AttributeList::AT_objc_gc: 1533ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian // Ignore these, these are type attributes, handled by ProcessTypeAttributes. 1534803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1535803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 15363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1537af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar case AttributeList::AT_always_inline: 1538af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 1539b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek case AttributeList::AT_analyzer_noreturn: 1540b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek HandleAnalyzerNoReturnAttr (D, Attr, S); break; 15413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 15423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1543803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 15443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1545803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 15463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 15473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 15483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 15493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1550803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1551803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 1552cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break; 15533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1554eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 15553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 15563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 15573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 155817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 15593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1560bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 156173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 1562b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break; 15633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 15643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 1565026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S); 1566026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner break; 15673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 15686e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break; 1569803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1570803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1571803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 15720db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner case AttributeList::AT_objc_exception: 15730db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner HandleObjCExceptionAttr(D, Attr, S); 15740db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner break; 1575f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1576fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 15779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1578770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1579232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1580232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1581f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1582d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; 15835bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; 158455d3aaf9a537888734762170823daf750ea9036dEli Friedman case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break; 158505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson case AttributeList::IgnoredAttribute: 158605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson // Just ignore 158705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson break; 1588803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1589d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 1590803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1591803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1593803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1594803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1595803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 1596803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1597803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 1598803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 1599803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1600803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1601803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1602803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 16040744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 16050744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 16060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 16070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 16080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 16090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 16100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 1611803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 16120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 16130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 16140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 16150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 16160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 16170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 16180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 16190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 16200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 16210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 16220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 16230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 16240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1625