SemaDeclAttr.cpp revision d3f2c10f881311831a84114179342ff4db55e0c3
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" 18e4858a65a93fb36c099d8dd2ea0a98e33e77687eDaniel Dunbar#include "clang/Basic/Diagnostic.h" 19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h" 2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h" 216e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h> 226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang; 236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Helper functions 26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 28d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic const FunctionType *getFunctionType(Decl *d) { 296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType Ty; 306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) 316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) 336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getType(); 346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) 356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = decl->getUnderlyingType(); 366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Ty->isFunctionPointerType()) 406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Ty = Ty->getAsPointerType()->getPointeeType(); 41d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 42d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return Ty->getAsFunctionType(); 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 453568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 48d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function 49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C 50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method. 513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) { 52d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return getFunctionType(d) || isa<ObjCMethodDecl>(d); 53d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar} 543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 55d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument 56d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed 57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod. 58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) { 59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 60d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return isa<FunctionTypeProto>(FnTy); 61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } else { 62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar assert(isa<ObjCMethodDecl>(d)); 63d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar return true; 64d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar } 653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method 68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use 69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first). 703568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) { 71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 72d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getNumArgs(); 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getNumParams(); 763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 793568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 80d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getArgType(Idx); 833568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 843568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType(); 853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (const FunctionType *FnTy = getFunctionType(d)) { 90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); 913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 933568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 943568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 963568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 99b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 102b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 1076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 1116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 114085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const PointerType *PT = T->getAsPointerType(); 115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 119085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 120085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 121085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 122085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 123085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 124085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 125085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 128085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 129e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 130e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 131e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 132e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 137803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 138803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 140545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 142545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 147545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 148803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 149803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 152545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 154803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 156803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "ext_vector_type", sizeExpr->getSourceRange()); 1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 161b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 163b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner curType.getAsString()); 1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 172803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 176803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 178803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 184065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 190803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 195065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 197803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, 198803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("vector_size"), 199803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 200065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 201065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 202065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 203065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 204545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 205803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 207065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 209545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 211803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 212803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 213803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "vector_size", sizeExpr->getSourceRange()); 214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 218b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 219b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 234b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 235803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 236b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType.getAsString()); 237065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 239803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 245803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size, 246803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 247065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 250803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 251803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 252065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 254065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 255065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 256065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 257803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 258065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 259065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 260065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 261065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 262065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 265803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 267545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 268803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 269803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 2743b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar TD->addAttr(new PackedAttr(1)); 2756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 279803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 280803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), 281803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner diag::warn_attribute_ignored_for_field_of_type, 282803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName(), FD->getType().getAsString()); 2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 2843b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar FD->addAttr(new PackedAttr(1)); 2856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 286803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored, 287803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName()); 2886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 29196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 29296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 29396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 29496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek std::string("0")); 29596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 29696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 29796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 29896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 29996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 30096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 30196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek ID->addAttr(new IBOutletAttr()); 30296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 30396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 30496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 30596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 309d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", "function"); 312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 315d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek Expr *Ex = static_cast<Expr *>(Attr.getArg(0)); 326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 3376e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange()); 338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 340465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 341465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 344d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!getFunctionOrMethodArgType(d, x)->isPointerType()) { 345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 349eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 351eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 352eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 353eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // If no arguments were specified to __attribute__((nonnull)) then all 3557fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // pointer arguments have a nonnull attribute. 3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 357d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) 358d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (getFunctionOrMethodArgType(d, I)->isPointerType()) 359d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar NonNullArgs.push_back(I); 3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3677fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3687fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3697fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3707fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek d->addAttr(new NonNullAttr(start, size)); 371eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 372eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 373803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 375545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 377803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 381545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 386803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 387803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "alias", std::string("1")); 3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 399803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 401545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 402803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 403803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 406d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar 407d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d)) { 408803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 409803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "noreturn", "function"); 4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 41673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 41773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 41873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 41973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 42073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek std::string("0")); 42173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 42373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 424d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) { 42573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 426356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek "unused", "variable and function"); 42773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 42873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 42973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 43073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek d->addAttr(new UnusedAttr()); 43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 4333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 4363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 4373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "1", E->getSourceRange()); 4473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!Fn) { 4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "function"); 4563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new ConstructorAttr(priority)); 4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "1", E->getSourceRange()); 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4816782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "function"); 4843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new DestructorAttr(priority)); 4883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 490803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 492545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 493803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 494803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 501803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 503545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 504803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 505803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 509545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 514803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 515803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", std::string("1")); 5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 5256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 532803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 533803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", TypeStr); 5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 540aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5416e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson if (!Attr.getParameterName()) { 542aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 543aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson "objc_gc", std::string("1")); 544aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 545aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 546aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 547aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson if (Attr.getNumArgs() != 0) { 548aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 549aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson std::string("1")); 550aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 551aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 552aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 553aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson const char *TypeStr = Attr.getParameterName()->getName(); 554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson unsigned TypeLen = Attr.getParameterName()->getLength(); 555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson ObjCGCAttr::GCAttrTypes type; 557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 558aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4)) 559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Weak; 5606e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6)) 561aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Strong; 562aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson else { 563aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 564aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson "objc_gc", TypeStr); 565aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 566aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 567aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 568aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson d->addAttr(new ObjCGCAttr(type)); 569aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson} 570aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 5719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (!Attr.getParameterName()) { 5739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 5749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff "blocks", std::string("1")); 5759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 5799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 5809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff std::string("1")); 5819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff const char *TypeStr = Attr.getParameterName()->getName(); 5849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff unsigned TypeLen = Attr.getParameterName()->getLength(); 5859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 5879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5)) 5899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 5909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 5919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 5929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff "blocks", TypeStr); 5939eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5959eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5969eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff d->addAttr(new BlocksAttr(type)); 5979eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 5989eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 599770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) { 600770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // check the attribute arguments. 601770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 2) { 602770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0, 1 or 2"); 603770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 604770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 605770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 606770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int sentinel = 0; 607770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 0) { 608770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(0)); 609770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 610770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 611770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 612770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson "sentinel", "1", E->getSourceRange()); 613770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 614770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 615770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson sentinel = Idx.getZExtValue(); 616770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 617770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (sentinel < 0) { 618770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero, 619770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson E->getSourceRange()); 620770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 621770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 622770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 623770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 624770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson int nullPos = 0; 625770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (Attr.getNumArgs() > 1) { 626770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson Expr *E = static_cast<Expr *>(Attr.getArg(1)); 627770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson llvm::APSInt Idx(32); 628770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!E->isIntegerConstantExpr(Idx, S.Context)) { 629770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 630770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson "sentinel", "2", E->getSourceRange()); 631770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 632770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 633770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson nullPos = Idx.getZExtValue(); 634770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 635770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (nullPos > 1 || nullPos < 0) { 636770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: This error message could be improved, it would be nice 637770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // to say what the bounds actually are. 638770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one, 639770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson E->getSourceRange()); 640770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 641770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 642770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 643770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 644770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { 645770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson QualType FT = FD->getType(); 646770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!FT->getAsFunctionTypeProto()->isVariadic()) { 647770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 648770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 649770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 650770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) { 651770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson if (!MD->isVariadic()) { 652770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); 653770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 654770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 655770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } else { 656770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 657770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson "sentinel", "function or method"); 658770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson return; 659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson } 660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 661770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson // FIXME: Actually create the attribute. 662770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson} 663770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson 664803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 666545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 668803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 6736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 677545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 678803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 679803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 6846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 686803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 688545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 689803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 690803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 697803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 699545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 700803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 708803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 710545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 712803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 7136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 719803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 721545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 723803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 7286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 730232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { 731232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 732232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 733232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 734232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson std::string("0")); 735232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 736232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 737232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 738232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson d->addAttr(new ConstAttr()); 739232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 740232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 741232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { 742232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson // check the attribute arguments. 743232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson if (Attr.getNumArgs() != 0) { 744232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 745232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson std::string("0")); 746232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson return; 747232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson } 748232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 749232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson d->addAttr(new PureAttr()); 750232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson} 751232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson 7526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 754803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 756545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 757803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 7586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("1")); 7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 762545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 763803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 764803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("3")); 7656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 768d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) { 769803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 770803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "format", "function"); 7716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 7756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 7773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 7786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 7796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 780545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 781545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 7856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 7866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 7876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 7886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 7916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 7926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 793085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 797803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 798803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 799803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 801085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 802085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 803085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 8056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 808803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 809545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner "format", Attr.getParameterName()->getName()); 8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 814545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 815803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 816803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 817803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 8186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 8196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 823803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 8246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 8256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 8296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 8306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 8323568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 8336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 834085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 835085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 836085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 837085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "a CFString", IdxExpr->getSourceRange()); 838085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 839085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 840085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 8416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 8426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 843803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 8456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 846085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 847085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "an NSString", IdxExpr->getSourceRange()); 8486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 854085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 855085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "a string type", IdxExpr->getSourceRange()); 8566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 860545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 862803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 863803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 8646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 8656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 8703568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 8716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 8726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 873803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 8746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any variable 8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the input is just the current time + the format string 8806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 8816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 882803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FirstArgExpr->getSourceRange()); 8846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 8876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 888803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 8896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 8906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 8946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 8956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 8980b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 8996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 900545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 9010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 9026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner std::string("0")); 9036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 906bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This shouldn't be restricted to typedefs 907bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 908bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!TD || !TD->getUnderlyingType()->isUnionType()) { 9090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 9106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "transparent_union", "union"); 9116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 914bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 915bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 916bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: Should we do a check for RD->isDefinition()? 917bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 918bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This isn't supposed to be restricted to pointers, but otherwise 919bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // we might silently generate incorrect code; see following code 920bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman for (int i = 0; i < RD->getNumMembers(); i++) { 921bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!RD->getMember(i)->getType()->isPointerType()) { 922bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 923bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 924bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 925bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 9266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 927bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This is a complete hack; we should be properly propagating 928bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // transparent_union through Sema. That said, this is close enough to 929bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // correctly compile all the common cases of transparent_union without 930bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // errors or warnings 931bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman QualType NewTy = S.Context.VoidPtrTy; 932bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman NewTy.addConst(); 933bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TD->setUnderlyingType(NewTy); 9346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9360b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 938545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 9390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 9400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("1")); 9416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 943545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 9446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 9456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 9476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 9486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 9490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 9506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 9536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 9546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 9556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 956803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 9576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 958545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 959803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 960803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 9636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 9646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 965545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 9666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 9676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 9686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 9696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 9706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 97149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 97249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 97349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 974803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 975803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 976803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "aligned", alignmentExpr->getSourceRange()); 97749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 97849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 97949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 9806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 9820b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 983065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 984fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 985fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 986fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 987fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 988fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 9890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 994fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 9950b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 9960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("0")); 997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 1001fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 10020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 1003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1004fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 1006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 1007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 1009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 1010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 1011fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 1012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 1013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 1016fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 1017fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 1018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 1019fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 1020fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 1021fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 1022fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 1023fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 1024fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 1025fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 1026fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 1027fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 1028fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1029fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 1030fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 1031fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 1032fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 10330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1034fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 10350b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 1036fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1037fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 1038fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 10390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 1040fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1041fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1042fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1043fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 1044fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1045fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 1046fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 1047fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 1048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 10490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 10500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 1051fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1052fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: Need proper fixed-width types 1055fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 1056fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 1057fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 10580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 1059fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 10610b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 1062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 1063fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 1064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 1065fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 10660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 1067fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 10680b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 1069fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 1071fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 1072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 10730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 1074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 10750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 1076fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1077fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 1078fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 10790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 1080fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 10810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 1082fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 10830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 1084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1085fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 1086fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 10870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 1088fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 10890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 1090fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 10910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 1092fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 1093fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1094fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1095fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 10960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1097fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 1098fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 10990b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1100fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1101fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1102fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1103fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1104fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1105fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1106fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1107fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 11080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 11090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 11100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 11110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 11120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1113803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 1114803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1115803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1116803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1117803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 11183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1119803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1120803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 1121803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1122803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 11233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 11243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 11253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1126803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 11273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1128803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 11293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 11303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 11313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 11323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 11353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1136eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 11373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 11383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 11393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 11403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 114173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 11423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 11433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 11443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1145803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1146803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1148aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; 11499eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1150770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; 1151232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; 1152232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; 1153803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1154803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 1155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 1156803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 1157803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr->getName()->getName()); 1158803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 1159803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1160803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1161803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1164803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 1165803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1166803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 1167803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 1168803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1169803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1170803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1171803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1172803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 11730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 11740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 11750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 11760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 11770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 11780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 11790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 1180803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 11810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 11820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 11830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 11840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 11850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 11860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 11870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 11880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 11890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 11900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 11910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 11920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 11930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1194