SemaDeclAttr.cpp revision f98aba35e6c3da5aae61843fc01334939e4e12ec
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)) { 59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return isa<FunctionTypeProto>(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) { 70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getNumArgs(); 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getNumParams(); 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 80d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getArgType(Idx); 823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 833568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType(); 843568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 933568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 943568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 97b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 101b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const PointerType *PT = T->getAsPointerType(); 114085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 119085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 120085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 121085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 122085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 123085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 124085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 125085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 128e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 129e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 130e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 131e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 136803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 137803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 138545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 141545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 146545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 1473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 150545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 152803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 153fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 154fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "ext_vector_type" << sizeExpr->getSourceRange(); 1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 159b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 160d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType; 1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 168fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 169fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 173803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 179065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 184065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 194fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 195fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc()); 196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 198065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 199065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 200545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 2013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 202065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 204545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 208fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "vector_size" << sizeExpr->getSourceRange(); 209065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 213b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 214b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 229b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 230d162584991885ab004a02573a73ce06422b921fcChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; 231065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 233803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size) 240fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 241065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 244fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size) 245fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << sizeExpr->getSourceRange(); 246065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 248065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 249065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 250065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 251803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 252065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 253065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 254065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 255065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 256065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 261545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 2623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 2673b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar TD->addAttr(new PackedAttr(1)); 2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 272803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 273fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type) 27408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << Attr.getName() << FD->getType(); 2756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 2763b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar FD->addAttr(new PackedAttr(1)); 2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 2783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName(); 2796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 28196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 2843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 28596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 28796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 29196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek ID->addAttr(new IBOutletAttr()); 29296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 29396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 29496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 29596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 299d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 300fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 301fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << "function"; 302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 303eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 304eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 305d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 315f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek Expr *Ex = static_cast<Expr *>(*I); 316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 318fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 319fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 326fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 32730bc96544346bea42921cf6837e66cef80d664b4Chris Lattner << "nonnull" << I.getArgNum() << Ex->getSourceRange(); 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 330465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 331465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 33446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, x); 33546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (!T->isPointerType() && !T->isBlockPointerType()) { 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 337fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only) 338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "nonnull" << Ex->getSourceRange(); 3397fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 341eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 3457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // If no arguments were specified to __attribute__((nonnull)) then all 3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // pointer arguments have a nonnull attribute. 3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 34846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) { 34946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek QualType T = getFunctionOrMethodArgType(d, I); 35046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek if (T->isPointerType() || T->isBlockPointerType()) 351d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 35246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek } 3537fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3557fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek d->addAttr(new NonNullAttr(start, size)); 364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 368545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 3693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 373545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 378fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 3793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "alias" << 1; 3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 391af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, 392af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar Sema &S) { 393af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar // check the attribute arguments. 394af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar if (Attr.getNumArgs() != 0) { 3953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 396af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar return; 397af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar } 398af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 399af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar d->addAttr(new AlwaysInlineAttr()); 400af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar} 401af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar 402803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 404545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 408d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 409d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d)) { 410fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 411fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "noreturn" << "function"; 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 41873798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 41973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 42073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 4213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 42373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 42473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 425d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 426fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 427fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "unused" << "variable and function"; 42873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 42973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 43073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek d->addAttr(new UnusedAttr()); 43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 43373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 4343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 437fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 438fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 447fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 4483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "constructor" << 1 << E->getSourceRange(); 4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!Fn) { 456fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 457fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "constructor" << "function"; 4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new ConstructorAttr(priority)); 4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 467fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 468fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0 or 1"; 4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 4783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "destructor" << 1 << E->getSourceRange(); 4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4846782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 485fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 486fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "destructor" << "function"; 4873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new DestructorAttr(priority)); 4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 493803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 495545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 4963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 503bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) { 504bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian // check the attribute arguments. 505bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian if (Attr.getNumArgs() != 0) { 506bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 507bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian return; 508bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian } 509bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 510bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian d->addAttr(new UnavailableAttr()); 511bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian} 512bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian 513803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 515545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 5163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 520545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 525fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "visibility" << 1; 5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 54308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr; 5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 550aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5516e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson if (!Attr.getParameterName()) { 552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 5533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "objc_gc" << 1; 554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson if (Attr.getNumArgs() != 0) { 5583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 560aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 561aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 562aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 563aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson ObjCGCAttr::GCAttrTypes type; 56492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("weak")) { 56524b93f2debe1fdb98c7b03a79486a02bf8b9c9e4Fariborz Jahanian if (isa<FieldDecl>(d) && !isa<ObjCIvarDecl>(d)) 5662682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field); 567aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Weak; 5682682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian } 56992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner else if (Attr.getParameterName()->isStr("strong")) 570aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Strong; 571aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson else { 572fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 5733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "objc_gc" << Attr.getParameterName(); 574aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 575aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 576aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 577aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson d->addAttr(new ObjCGCAttr(type)); 578aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson} 579aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 580fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanianstatic void HandleObjCNSObject(Decl *d, const AttributeList &Attr, Sema &S) { 581fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (Attr.getNumArgs() != 0) { 582fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 583fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 584fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 585fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (TypedefDecl *TD = dyn_cast<TypedefDecl>(d)) { 586fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian QualType T = TD->getUnderlyingType(); 587fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian if (!T->isPointerType() || 588fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian !T->getAsPointerType()->getPointeeType()->isRecordType()) { 589fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian S.Diag(TD->getLocation(), diag::err_nsobject_attribute); 590fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian return; 591fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 592fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian } 593fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian d->addAttr(new ObjCNSObjectAttr); 594fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian} 595fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian 596f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void 597f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) { 598f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (Attr.getNumArgs() != 0) { 599f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 600f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 601f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 602f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 603f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor if (!isa<FunctionDecl>(D)) { 604f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function); 605f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor return; 606f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor } 607f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 608f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor D->addAttr(new OverloadableAttr); 609f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor} 610f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor 6119eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6129eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (!Attr.getParameterName()) { 613fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 6143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << 1; 6159eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6169eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6179eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6189eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 6193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 6209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6219eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6229eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6239eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 62492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner if (Attr.getParameterName()->isStr("byref")) 6259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 6269eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 627fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 6283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "blocks" << Attr.getParameterName(); 6299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 6309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 6319eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 6329eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff d->addAttr(new BlocksAttr(type)); 6339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 6349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 635770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 636770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 637770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 638fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) 639fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0, 1 or 2"; 640770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 641770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 642770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 643770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 644770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 645770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 646770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 647770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 648fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 1 << E->getSourceRange(); 650770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 651770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 652770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 653770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 654770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 655fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero) 656fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 657770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 658770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 661770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 662770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 663770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 664770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 665770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 666fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 6673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "sentinel" << 2 << E->getSourceRange(); 668770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 669770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 670770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 671770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 672770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 673770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 674770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 675fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one) 676fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << E->getSourceRange(); 677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 679770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 680770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson QualType FT = FD->getType(); 683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!FT->getAsFunctionTypeProto()->isVariadic()) { 684770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 685770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 690770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 691770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 693fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 694fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "sentinel" << "function or method"; 695770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: Actually create the attribute. 699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 703545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 713545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7177b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 7182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 7192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (isa<VarDecl>(d)) { 7202f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov d->addAttr(new DLLImportAttr()); 7212f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7222f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7232f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7242f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov FunctionDecl *FD = dyn_cast<FunctionDecl>(d); 7252f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 7262f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7272f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov << "dllimport" << "function or variable"; 7282f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7292f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7312f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllimport attribute is ignored for inlined functions. 7322f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 7332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 7342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 7352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7362f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7372f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7382f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // The attribute is also overridden by a subsequent declaration as dllexport. 7392f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Warning is emitted. 7402f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov for (AttributeList *nextAttr = Attr.getNext(); nextAttr; 7412f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov nextAttr = nextAttr->getNext()) { 7422f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (nextAttr->getKind() == AttributeList::AT_dllexport) { 7432f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 7442f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7452f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7462f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7482f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (d->getAttr<DLLExportAttr>()) { 7492f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport"; 7502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7512f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7522f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 756803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 758545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 7593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7627b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 7632f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Attribute can be applied only to functions or variables. 7642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (isa<VarDecl>(d)) { 7652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov d->addAttr(new DLLExportAttr()); 7662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7672f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7682f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7692f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov FunctionDecl *FD = dyn_cast<FunctionDecl>(d); 7702f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (!FD) { 7712f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 7722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov << "dllexport" << "function or variable"; 7732f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7742f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // Currently, the dllexport attribute is ignored for inlined functions, 7772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // unless the -fkeep-inline-functions flag has been used. Warning is emitted; 7782f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov if (FD->isInline()) { 7792f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov // FIXME: ... unless the -fkeep-inline-functions flag has been used. 7802f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport"; 7812f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov return; 7822f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov } 7832f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov 7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 7856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 78717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbarstatic void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) { 78817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Attribute has no arguments. 78917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (Attr.getNumArgs() != 1) { 79017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 79117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 79217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 79317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 79417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // Make sure that there is a string literal as the sections's single 79517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // argument. 79617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar StringLiteral *SE = 79717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0))); 79817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar if (!SE) { 79917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar // FIXME 80017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 80117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar return; 80217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar } 80317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar d->addAttr(new SectionAttr(std::string(SE->getStrData(), 80417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar SE->getByteLength()))); 80517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar} 80617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar 807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 809545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8137b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8147b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute can be applied only to functions. 8157b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 8167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8177b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "function"; 8187b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 8197b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 8207b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8217b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 8227b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<FastCallAttr>()) { 8237b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 8247b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "stdcall" << "fastcall"; 8257b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 8267b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 8277b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 8296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8327b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // Attribute has no arguments. 833545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8377b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8387b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (!isa<FunctionDecl>(d)) { 8397b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 8407b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "function"; 8417b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 8427b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 8437b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov // stdcall and fastcall attributes are mutually incompatible. 8457b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov if (d->getAttr<StdCallAttr>()) { 8467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible) 8477b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov << "fastcall" << "stdcall"; 8487b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov return; 8497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov } 8507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 856545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 8626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 864232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 865232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 866232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 8673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 868232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 869232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 870232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 871232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson d->addAttr(new ConstAttr()); 872232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 873232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 874232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 875232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 876232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 8773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 878232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 879232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 880232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 881232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson d->addAttr(new PureAttr()); 882232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 883232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 884f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { 88589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // Match gcc which ignores cleanup attrs when compiling C++. 88689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (S.getLangOptions().CPlusPlus) 88789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 88889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 889f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!Attr.getParameterName()) { 890f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 891f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 892f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 893f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 894f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (Attr.getNumArgs() != 0) { 895f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 896f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 897f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 898f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 899f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson VarDecl *VD = dyn_cast<VarDecl>(d); 900f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 901f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!VD || !VD->hasLocalStorage()) { 902f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; 903f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 904f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 905f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 906f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson // Look up the function 90747b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), 90847b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor Sema::LookupOrdinaryName); 909f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!CleanupDecl) { 91089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << 911f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 912f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 913f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 914f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 915f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl); 916f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (!FD) { 91789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << 918f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 919f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 920f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 921f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 922f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson if (FD->getNumParams() != 1) { 92389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) << 924f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson Attr.getParameterName(); 925f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson return; 926f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson } 927f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 92889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // We're currently more strict than GCC about what function types we accept. 92989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson // If this ever proves to be a problem it should be easy to fix. 93089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType Ty = S.Context.getPointerType(VD->getType()); 93189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson QualType ParamTy = FD->getParamDecl(0)->getType(); 93289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson if (Ty != ParamTy) { 93389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson S.Diag(Attr.getLoc(), 93489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson diag::err_attribute_cleanup_func_arg_incompatible_type) << 93589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson Attr.getParameterName() << ParamTy << Ty; 93689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson return; 93789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson } 93889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson 939f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson d->addAttr(new CleanupAttr(FD)); 940f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson} 941f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson 9426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 9436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 944803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 946545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 947fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string) 9483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 1; 9496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 952545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 9533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3; 9546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 957d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 958fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 959fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "format" << "function"; 9606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 9646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 9656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 9663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 9676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 9686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 969545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 970545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 9716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 9736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 9746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 9756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 9766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 9776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 9806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 9816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 982085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 9836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 9856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 986803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 987803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 988803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 9896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 990085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 991085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 992085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 9936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 9946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 997fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) 998fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "format" << Attr.getParameterName()->getName(); 9996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 1003545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 1004803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 1005803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 1006fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 10086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 1012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 10133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 2 << IdxExpr->getSourceRange(); 10146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 10186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 10196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 10213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 10226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1023085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 1024085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 1025fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1026fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a CFString" << IdxExpr->getSourceRange(); 1027085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 1028085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 1029085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 10306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 10316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 1032803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 10336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1035fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1036fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "an NSString" << IdxExpr->getSourceRange(); 10376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 10406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 10416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 10426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 1043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_attribute_not) 1044fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "a string type" << IdxExpr->getSourceRange(); 10456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 1049545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 1050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 1051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 1052fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int) 10533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 10593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 10606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 10616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 1062803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any 10683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner // variable the input is just the current time + the format string. 10696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 10706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 1071fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter) 1072fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << FirstArgExpr->getSourceRange(); 10736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 1077fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) 10783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner << "format" << 3 << FirstArgExpr->getSourceRange(); 10796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 10836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 10846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 10860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 10870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 10886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1089545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 10903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 10916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1094bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This shouldn't be restricted to typedefs 1095bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 1096bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!TD || !TD->getUnderlyingType()->isUnionType()) { 1097fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) 1098fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "transparent_union" << "union"; 10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1102bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 1103bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 1104bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: Should we do a check for RD->isDefinition()? 1105bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 1106bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This isn't supposed to be restricted to pointers, but otherwise 1107bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // we might silently generate incorrect code; see following code 110844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor for (RecordDecl::field_iterator Field = RD->field_begin(), 110944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor FieldEnd = RD->field_end(); 111044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor Field != FieldEnd; ++Field) { 111144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor if (!Field->getType()->isPointerType()) { 1112bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 1113bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 1114bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 1115bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 11166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1117bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This is a complete hack; we should be properly propagating 1118bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // transparent_union through Sema. That said, this is close enough to 1119bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // correctly compile all the common cases of transparent_union without 1120bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // errors or warnings 1121bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman QualType NewTy = S.Context.VoidPtrTy; 1122bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman NewTy.addConst(); 1123bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TD->setUnderlyingType(NewTy); 11246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1128545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 11293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1132545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 11336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 11346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 11376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 11380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 11436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1145803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 11466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 1147545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 11483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; 11496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 11516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 11526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 1153545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 115949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 116049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 116149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 1162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 1163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) 1164fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "aligned" << alignmentExpr->getSourceRange(); 116549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 116649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 116749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1169fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 11700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 1171065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 1172fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 1173fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 1174fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 1175fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 1176fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 11770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 1178fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 1179fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 1180fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1181fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 1182fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 11833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; 1184fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1185fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1186fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1187fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1188fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 11890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1191fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1195fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1199fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 1204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 1206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 1207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 1208fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 1209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 1210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 1211fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 1212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 1213fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 1214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 1215fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1216fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1217fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1219fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 12200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1221fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 12220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1223fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1224fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1225fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 12260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1227fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1229fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1230fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1231fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1232fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1233fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1234fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1235fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 1236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl) 1237fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc()); 1238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1241f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Sync this with InitializePredefinedMacros; we need to match 1242f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // int8_t and friends, at least with glibc. 1243f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure 32/64-bit integers don't get defined to types of 1244f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // the wrong width on unusual platforms. 1245f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Make sure floating-point mappings are accurate 1246f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman // FIXME: Support XF and TF types 1247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1249fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 12503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name; 1251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 12533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1255fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 1256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 1257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 12580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 12600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1261fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 1263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 1264fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 12650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1266fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 12670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1268fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1269fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1270fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 12710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1272fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 12730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1274fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 12750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1276fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1277fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 12790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1280fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 12810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1282fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 12830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1285f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman case 128: 1286f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman if (!IntegerMode) { 1287f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name; 1288f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman return; 1289f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman } 1290f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType()); 1291fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1293fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 12940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1295fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 1296fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 12970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1298fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1299fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1300fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1303fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1304fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1305fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 13060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 13070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 13080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 13090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 13100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1311a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if 1312803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1315803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 13163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1317803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1318803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 1319803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1320803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 13213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 1322af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar case AttributeList::AT_always_inline: 1323af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar HandleAlwaysInlineAttr (D, Attr, S); break; 13243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 13253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 13273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1328803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 13293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 13303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 13313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 13323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1333803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1334803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 13353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 13373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 13383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 13393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 134017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break; 13413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 1342bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break; 134373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 13443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 13453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 13463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1347803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1349803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1350aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; 1351f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break; 1352fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break; 13539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1354770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1355232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1356232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1357f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; 1358803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1359803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 1360803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 136108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored) << Attr->getName(); 1362803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 1363803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1364803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1365803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1367803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1368803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 1369803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1370803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 1371803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 1372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1373803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1374803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1375803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 13770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 13780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 13790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 13800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 13810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 13820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 13830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 1384803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 13850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 13860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 13870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 13880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 13890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 13900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 13910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 13920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 13930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 13940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 13950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 13960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 13970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1398