SemaDeclAttr.cpp revision 3568249c2d72d58b835a22d9186f5a6b4fc4bcd6
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 286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic const FunctionTypeProto *getFunctionProto(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(); 416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (const FunctionType *FnTy = Ty->getAsFunctionType()) 436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType()); 446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return 0; 466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function 493568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information. 503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl is a (non-K&R) 523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar/// function or an Objective-C method. 533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) { 543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return getFunctionProto(d) || isa<ObjCMethodDecl>(d); 553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 563568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 573568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) { 593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (const FunctionTypeProto *proto = getFunctionProto(d)) { 603568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getNumArgs(); 613568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 623568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getNumParams(); 633568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 643568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { 673568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (const FunctionTypeProto *proto = getFunctionProto(d)) { 683568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->getArgType(Idx); 693568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 703568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType(); 713568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) { 753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (const FunctionTypeProto *proto = getFunctionProto(d)) { 763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return proto->isVariadic(); 773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } else { 783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar return cast<ObjCMethodDecl>(d)->isVariadic(); 793568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar } 803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar} 813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar 826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) { 83b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const PointerType *PT = T->getAsPointerType(); 84b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!PT) 856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 87b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType(); 886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!ClsT) 896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return false; 906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); 926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should we walk the chain of classes? 946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return ClsName == &Ctx.Idents.get("NSString") || 956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ClsName == &Ctx.Idents.get("NSMutableString"); 966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 98085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) { 99085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const PointerType *PT = T->getAsPointerType(); 100085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!PT) 101085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 102085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 103085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordType *RT = PT->getPointeeType()->getAsRecordType(); 104085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!RT) 105085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 106085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 107085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar const RecordDecl *RD = RT->getDecl(); 108085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (RD->getTagKind() != TagDecl::TK_struct) 109085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return false; 110085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 111085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return RD->getIdentifier() == &Ctx.Idents.get("__CFString"); 112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar} 113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar 114e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 115e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations 116e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===// 117e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner 1183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the 1193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (# 1203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args). 1213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 122803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr, 123803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Sema &S) { 124545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d); 125545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (tDecl == 0) { 126803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef); 127545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner return; 1286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner QualType curType = tDecl->getUnderlyingType(); 1316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 132545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 134803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 1356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 137545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 139803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "ext_vector_type", sizeExpr->getSourceRange()); 1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, we do not allow vectors to be defined 1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // in conjunction with complex types (pointers, arrays, functions, etc.). 146b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!curType->isIntegerType() && !curType->isRealFloatingType()) { 147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 148b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner curType.getAsString()); 1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // unlike gcc's vector_size attribute, the size is specified as the 1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // number of elements, not the number of bytes. 1536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); 1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 156803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 157803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Instantiate/Install the vector type, the number of elements is > 0. 161803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize)); 1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Remember this typedef decl, we will need it later for diagnostics. 163803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.ExtVectorDecls.push_back(tDecl); 1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 166065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 167065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to 168065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function 169065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates 170065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a 171065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar. 172065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size 173065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well 174065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type. 175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 176065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner QualType CurType; 177065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = VD->getType(); 179065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner CurType = TD->getUnderlyingType(); 181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else { 182803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, 183803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("vector_size"), 184803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner } 187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Check the attribute arugments. 189545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 190803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 191803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 1936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 194545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0)); 1956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner llvm::APSInt vecSize(32); 196803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) { 197803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 198803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "vector_size", sizeExpr->getSourceRange()); 199065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // navigate to the base type - we need to provide for vector pointers, 2026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vector arrays, and functions returning vectors. 203b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (CurType->isPointerType() || CurType->isArrayType() || 204b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType->isFunctionType()) { 2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner assert(0 && "HandleVector(): Complex type construction unimplemented"); 2066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner /* FIXME: rebuild the type from the inside out, vectorizing the inner type. 2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner do { 2086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (PointerType *PT = dyn_cast<PointerType>(canonType)) 2096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = PT->getPointeeType().getTypePtr(); 2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) 2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = AT->getElementType().getTypePtr(); 2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) 2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType = FT->getResultType().getTypePtr(); 2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } while (canonType->isPointerType() || canonType->isArrayType() || 2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner canonType->isFunctionType()); 2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner */ 2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the base type must be integer or float. 219b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) { 220803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type, 221b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner CurType.getAsString()); 222065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 224803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType)); 2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // vecSize is specified in bytes - convert to bits. 2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); 2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the vector size needs to be an integral multiple of the type size. 2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize % typeSize) { 230803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size, 231803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 232065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (vectorSize == 0) { 235803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_zero_size, 236803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner sizeExpr->getSourceRange()); 237065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner return; 2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 239065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 240065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // Success! Instantiate the vector type, the number of elements is > 0, and 241065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner // not required to be a power of 2, unlike GCC. 242803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner CurType = S.Context.getVectorType(CurType, vectorSize/typeSize); 243065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner 244065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 245065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner VD->setType(CurType); 246065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner else 247065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner cast<TypedefDecl>(D)->setUnderlyingType(CurType); 2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 250803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 252545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 0) { 253803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 254803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 2556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TagDecl *TD = dyn_cast<TagDecl>(d)) 25949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner TD->addAttr(new PackedAttr()); 2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { 2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // If the alignment is less than or equal to 8 bits, the packed attribute 2626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // has no effect. 2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!FD->getType()->isIncompleteType() && 264803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Context.getTypeAlign(FD->getType()) <= 8) 265803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), 266803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner diag::warn_attribute_ignored_for_field_of_type, 267803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName(), FD->getType().getAsString()); 2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else 26949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner FD->addAttr(new PackedAttr()); 2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else 271803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_ignored, 272803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr.getName()->getName()); 2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 27596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) { 27696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // check the attribute arguments. 27796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (Attr.getNumArgs() > 0) { 27896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 27996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek std::string("0")); 28096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek return; 28196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek } 28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // The IBOutlet attribute only applies to instance variables of Objective-C 28496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek // classes. 28596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d)) 28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek ID->addAttr(new IBOutletAttr()); 28796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek else 28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar); 28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek} 29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek 291eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { 292eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 293eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // GCC ignores the nonnull attribute on K&R style function 294eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // prototypes, so we ignore it as well 295eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek const FunctionTypeProto *proto = getFunctionProto(d); 296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!proto) { 297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", "function"); 299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 301eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned NumArgs = proto->getNumArgs(); 303eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 304eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The nonnull attribute only applies to pointers. 305eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::SmallVector<unsigned, 10> NonNullArgs; 306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek for (AttributeList::arg_iterator I=Attr.arg_begin(), 308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek E=Attr.arg_end(); I!=E; ++I) { 309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // The argument must be an integer constant expression. 312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek Expr *Ex = static_cast<Expr *>(Attr.getArg(0)); 313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek llvm::APSInt ArgNum(32); 314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) { 315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek unsigned x = (unsigned) ArgNum.getZExtValue(); 321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek if (x < 1 || x > NumArgs) { 323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 3246e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek "nonnull", llvm::utostr_32(I.getArgNum()), Ex->getSourceRange()); 325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek return; 326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 327465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek 328465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek --x; 329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // Is the function argument a pointer type? 331b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner if (!proto->getArgType(x)->isPointerType()) { 332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek // FIXME: Should also highlight argument in decl. 333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only, 334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek "nonnull", Ex->getSourceRange()); 3357fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek continue; 336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek NonNullArgs.push_back(x); 339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 3417fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // If no arguments were specified to __attribute__((nonnull)) then all 3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek // pointer arguments have a nonnull attribute. 3437fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3447fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned idx = 0; 3457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek for (FunctionTypeProto::arg_type_iterator 3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek I=proto->arg_type_begin(), E=proto->arg_type_end(); I!=E; ++I, ++idx) 3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if ((*I)->isPointerType()) 3497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek NonNullArgs.push_back(idx); 3507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3517fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek if (NonNullArgs.empty()) { 3527fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers); 3537fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek return; 3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek } 355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek } 3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek 3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned* start = &NonNullArgs[0]; 3587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek unsigned size = NonNullArgs.size(); 3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek std::sort(start, start + size); 3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek d->addAttr(new NonNullAttr(start, size)); 361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek} 362eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek 363803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 365545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 367803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 3686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 371545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 377803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "alias", std::string("1")); 3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *Alias = Str->getStrData(); 3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned AliasLen = Str->getByteLength(); 3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: check if target symbol exists in current file 3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); 3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 389803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { 3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 391545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 392803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 393803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 3973568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (!isa<FunctionDecl>(d) && !isa<ObjCMethodDecl>(d)) { 398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 399803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "noreturn", "function"); 4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoReturnAttr()); 4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 40673798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 40773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek // check the attribute arguments. 40873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek if (Attr.getNumArgs() != 0) { 40973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 41073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek std::string("0")); 41173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 41273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 41373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 414356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek if (!isa<VarDecl>(d) && !getFunctionProto(d)) { 41573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 416356b63a6668d8b010b53921941576189ee4bd459Ted Kremenek "unused", "variable and function"); 41773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek return; 41873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek } 41973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 42073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek d->addAttr(new UnusedAttr()); 42173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek} 42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek 4233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 4263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 4273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 4353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 4363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "1", E->getSourceRange()); 4373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); 4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!Fn) { 4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "constructor", "function"); 4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new ConstructorAttr(priority)); 4503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar // check the attribute arguments. 4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) { 4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0 or 1"); 4563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar int priority = 65535; // FIXME: Do not hardcode such constants. 4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (Attr.getNumArgs() > 0) { 4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar Expr *E = static_cast<Expr *>(Attr.getArg(0)); 4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar llvm::APSInt Idx(32); 4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar if (!E->isIntegerConstantExpr(Idx, S.Context)) { 4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "1", E->getSourceRange()); 4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar priority = Idx.getZExtValue(); 4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4716782fc6925a85c3772253e272745589a0c799c15Anders Carlsson if (!isa<FunctionDecl>(d)) { 4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar "destructor", "function"); 4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar return; 4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar } 4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar d->addAttr(new DestructorAttr(priority)); 4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar} 4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar 480803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 482545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 483803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 484803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 4856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 4886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DeprecatedAttr()); 4896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 4906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 491803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) { 4926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 493545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 494803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 495803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 4966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 499545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *Arg = static_cast<Expr*>(Attr.getArg(0)); 5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Arg = Arg->IgnoreParenCasts(); 5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *Str = dyn_cast<StringLiteral>(Arg); 5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Str == 0 || Str->isWide()) { 504803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 505803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", std::string("1")); 5066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner const char *TypeStr = Str->getStrData(); 5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned TypeLen = Str->getByteLength(); 5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner VisibilityAttr::VisibilityTypes type; 5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) 5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::DefaultVisibility; 5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) 5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; 5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) 5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::HiddenVisibility; // FIXME 5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) 5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner type = VisibilityAttr::ProtectedVisibility; 5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner else { 522803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 523803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "visibility", TypeStr); 5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new VisibilityAttr(type)); 5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 530aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5316e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson if (!Attr.getParameterName()) { 532aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 533aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson "objc_gc", std::string("1")); 534aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 535aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 536aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 537aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson if (Attr.getNumArgs() != 0) { 538aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 539aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson std::string("1")); 540aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 541aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 542aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 543aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson const char *TypeStr = Attr.getParameterName()->getName(); 544aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson unsigned TypeLen = Attr.getParameterName()->getLength(); 545aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 546aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson ObjCGCAttr::GCAttrTypes type; 547aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 548aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson if (TypeLen == 4 && !memcmp(TypeStr, "weak", 4)) 549aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Weak; 5506e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson else if (TypeLen == 6 && !memcmp(TypeStr, "strong", 6)) 551aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson type = ObjCGCAttr::Strong; 552aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson else { 553aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson "objc_gc", TypeStr); 555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson return; 556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson } 557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 558aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson d->addAttr(new ObjCGCAttr(type)); 559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson} 560aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson 5619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (!Attr.getParameterName()) { 5639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 5649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff "blocks", std::string("1")); 5659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (Attr.getNumArgs() != 0) { 5699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 5709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff std::string("1")); 5719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5739eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff const char *TypeStr = Attr.getParameterName()->getName(); 5749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff unsigned TypeLen = Attr.getParameterName()->getLength(); 5759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff BlocksAttr::BlocksAttrTypes type; 5779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5)) 5799eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff type = BlocksAttr::ByRef; 5809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff else { 5819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 5829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff "blocks", TypeStr); 5839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff return; 5849eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff } 5859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 5869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff d->addAttr(new BlocksAttr(type)); 5879eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff} 5889eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff 589803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { 5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 591545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 592803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 593803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new WeakAttr()); 5986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 600803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 602545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 603803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 604803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLImportAttr()); 6096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 611803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 613545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 614803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 615803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new DLLExportAttr()); 6206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 622803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 624545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 625803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 626803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new StdCallAttr()); 6316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 633803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 635545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 636803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 637803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FastCallAttr()); 6426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 644803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 646545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 647803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 648803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("0")); 6496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new NoThrowAttr()); 6536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 6546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes 6566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 657803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { 6586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 659545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (!Attr.getParameterName()) { 660803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, 6616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("1")); 6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 665545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 2) { 666803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 667803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("3")); 6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // GCC ignores the format attribute on K&R style function 6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // prototypes, so we ignore it as well 6733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (!isFunctionOrMethod(d)) { 674803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "format", "function"); 6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: in C++ the implicit 'this' function parameter also counts. 6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // this is needed in order to be compatible with GCC 6816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the index must start in 1 and the limit is numargs+1 6823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar unsigned NumArgs = getFunctionOrMethodNumArgs(d); 6836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned FirstIdx = 1; 6846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 685545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner const char *Format = Attr.getParameterName()->getName(); 686545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner unsigned FormatLen = Attr.getParameterName()->getLength(); 6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Normalize the argument, __foo__ becomes foo. 6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && 6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { 6916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Format += 2; 6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FormatLen -= 4; 6936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 6946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool Supported = false; 6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_NSString = false; 6976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner bool is_strftime = false; 698085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar bool is_CFString = false; 6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner switch (FormatLen) { 7016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner default: break; 702803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 5: Supported = !memcmp(Format, "scanf", 5); break; 703803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 6: Supported = !memcmp(Format, "printf", 6); break; 704803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case 7: Supported = !memcmp(Format, "strfmon", 7); break; 7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner case 8: 706085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || 707085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_NSString = !memcmp(Format, "NSString", 8)) || 708085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar (is_CFString = !memcmp(Format, "CFString", 8)); 7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner break; 7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!Supported) { 713803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, 714545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner "format", Attr.getParameterName()->getName()); 7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // checks for the 2nd argument 719545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0)); 720803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt Idx(32); 721803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) { 722803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 7236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 7246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { 728803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 7296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("2"), IdxExpr->getSourceRange()); 7306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Do we need to bounds check? 7346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned ArgIdx = Idx.getZExtValue() - 1; 7356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // make sure the format string is really a string 7373568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar QualType Ty = getFunctionOrMethodArgType(d, ArgIdx); 7386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 739085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (is_CFString) { 740085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar if (!isCFStringType(Ty, S.Context)) { 741085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 742085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "a CFString", IdxExpr->getSourceRange()); 743085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar return; 744085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } 745085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar } else if (is_NSString) { 7466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: do we need to check if the type is NSString*? What are 7476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the semantics? 748803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!isNSStringType(Ty, S.Context)) { 7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 7506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 751085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 752085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "an NSString", IdxExpr->getSourceRange()); 7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (!Ty->isPointerType() || 7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner !Ty->getAsPointerType()->getPointeeType()->isCharType()) { 7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: Should highlight the actual expression that has the 7586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // wrong type. 759085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar S.Diag(Attr.getLoc(), diag::err_format_attribute_not, 760085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar "a string type", IdxExpr->getSourceRange()); 7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the 3rd argument 765545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1)); 766803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner llvm::APSInt FirstArg(32); 767803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) { 768803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int, 7696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 7706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check if the function is variadic if the 3rd argument non-zero 7746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 7753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar if (isFunctionOrMethodVariadic(d)) { 7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner ++NumArgs; // +1 for ... 7776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else { 778803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); 7796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // strftime requires FirstArg to be 0 because it doesn't read from any variable 7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // the input is just the current time + the format string 7856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (is_strftime) { 7866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (FirstArg != 0) { 787803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter, 7886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner FirstArgExpr->getSourceRange()); 7896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // if 0 it disables parameter checking (to use with e.g. va_list) 7926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } else if (FirstArg != 0 && FirstArg != NumArgs) { 793803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds, 7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "format", std::string("3"), FirstArgExpr->getSourceRange()); 7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 7966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 7976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 7986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new FormatAttr(std::string(Format, FormatLen), 7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Idx.getZExtValue(), FirstArg.getZExtValue())); 8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8020b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr, 8030b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner Sema &S) { 8046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 805545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 0) { 8060b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 8076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner std::string("0")); 8086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 811bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This shouldn't be restricted to typedefs 812bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TypedefDecl *TD = dyn_cast<TypedefDecl>(d); 813bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!TD || !TD->getUnderlyingType()->isUnionType()) { 8140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type, 8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner "transparent_union", "union"); 8166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 819bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl(); 820bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 821bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: Should we do a check for RD->isDefinition()? 822bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman 823bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This isn't supposed to be restricted to pointers, but otherwise 824bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // we might silently generate incorrect code; see following code 825bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman for (int i = 0; i < RD->getNumMembers(); i++) { 826bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman if (!RD->getMember(i)->getType()->isPointerType()) { 827bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer); 828bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman return; 829bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 830bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman } 8316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 832bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // FIXME: This is a complete hack; we should be properly propagating 833bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // transparent_union through Sema. That said, this is close enough to 834bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // correctly compile all the common cases of transparent_union without 835bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman // errors or warnings 836bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman QualType NewTy = S.Context.VoidPtrTy; 837bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman NewTy.addConst(); 838bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman TD->setUnderlyingType(NewTy); 8396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 843545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() != 1) { 8440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 8450b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("1")); 8466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 848545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner Expr *argExpr = static_cast<Expr *>(Attr.getArg(0)); 8496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); 8506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // Make sure that there is a string literal as the annotation's single 8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // argument. 8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner if (!SE) { 8540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string); 8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), 8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner SE->getByteLength()))); 8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 8626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // check the attribute arguments. 863545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() > 1) { 864803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 865803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner std::string("1")); 8666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 8686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner 8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner unsigned Align = 0; 870545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner if (Attr.getNumArgs() == 0) { 8716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // FIXME: This should be the target specific maximum alignment. 8726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner // (For now we just use 128 bits which is the maximum on X86. 8736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner Align = 128; 8746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner return; 8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner } 87649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner 87749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); 87849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner llvm::APSInt Alignment(32); 879803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { 880803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int, 881803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner "aligned", alignmentExpr->getSourceRange()); 88249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner return; 88349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner } 88449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8)); 8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner} 886fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 8870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with 888065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type. 889fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 890fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute, 891fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 892fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer. 893fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 8940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) { 895fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // This attribute isn't documented, but glibc uses it. It changes 896fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // the width of an int or unsigned int to the specified size. 897fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 898fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Check that there aren't any arguments 899fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Attr.getNumArgs() != 0) { 9000b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, 9010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner std::string("0")); 902fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 903fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 904fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 905fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner IdentifierInfo *Name = Attr.getParameterName(); 906fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!Name) { 9070b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name); 908fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 909fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 910fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner const char *Str = Name->getName(); 911fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned Len = Name->getLength(); 912fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 913fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Normalize the attribute name, __foo__ becomes foo. 914fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (Len > 4 && Str[0] == '_' && Str[1] == '_' && 915fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str[Len - 2] == '_' && Str[Len - 1] == '_') { 916fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Str += 2; 917fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner Len -= 4; 918fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 919fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 920fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner unsigned DestWidth = 0; 921fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner bool IntegerMode = true; 922fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (Len) { 923fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 2: 924fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "QI", 2)) { DestWidth = 8; break; } 925fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; } 926fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; } 927fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; } 928fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; } 929fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; } 930fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; } 931fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; } 932fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; } 933fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 934fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 4: 935fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: glibc uses 'word' to define register_t; this is narrower than a 936fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // pointer on PIC16 and other embedded platforms. 937fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "word", 4)) 9380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 939fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "byte", 4)) 9400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getCharWidth(); 941fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 942fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 7: 943fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!memcmp(Str, "pointer", 7)) 9440b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner DestWidth = S.Context.Target.getPointerWidth(0); 945fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 946fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 947fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 948fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType OldTy; 949fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 950fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = TD->getUnderlyingType(); 951fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) 952fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner OldTy = VD->getType(); 953fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else { 9540b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(D->getLocation(), diag::err_attr_wrong_decl, "mode", 9550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner SourceRange(Attr.getLoc(), Attr.getLoc())); 956fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 957fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 958fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 959fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // FIXME: Need proper fixed-width types 960fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner QualType NewTy; 961fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner switch (DestWidth) { 962fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 0: 9630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode, Name->getName()); 964fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 965fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner default: 9660b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode, Name->getName()); 967fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner return; 968fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 8: 969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 9710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.SignedCharTy; 972fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 9730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedCharTy; 974fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 16: 976fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner assert(IntegerMode); 977fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (OldTy->isSignedIntegerType()) 9780b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.ShortTy; 979fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 9800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedShortTy; 981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 982fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 32: 983fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 9840b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.FloatTy; 985fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 9860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.IntTy; 987fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 9880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedIntTy; 989fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner case 64: 991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!IntegerMode) 9920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.DoubleTy; 993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (OldTy->isSignedIntegerType()) 9940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.LongLongTy; 995fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 9960b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner NewTy = S.Context.UnsignedLongLongTy; 997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner break; 998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (!OldTy->getAsBuiltinType()) 10010b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_not_primitive); 1002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else if (!(IntegerMode && OldTy->isIntegerType()) && 1003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner !(!IntegerMode && OldTy->isFloatingType())) { 10040b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner S.Diag(Attr.getLoc(), diag::err_mode_wrong_type); 1005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner } 1006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner 1007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner // Install the new type. 1008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) 1009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner TD->setUnderlyingType(NewTy); 1010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner else 1011fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner cast<ValueDecl>(D)->setType(NewTy); 1012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner} 10130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 10140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 10150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points 10160744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===// 10170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1018803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if 1019803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls. If the attribute is a type attribute, just 1020803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it. 1021803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { 1022803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner switch (Attr.getKind()) { 10233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break; 1024803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_address_space: 1025803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. 1026803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1027803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break; 10283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break; 10293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; 10303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break; 1031803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break; 10323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break; 1033803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break; 10343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break; 10353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_ext_vector_type: 10363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar HandleExtVectorTypeAttr(D, Attr, S); 10373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar break; 1038803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break; 1039803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; 10403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break; 1041eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break; 10423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; 10433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break; 10443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break; 10453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break; 104673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break; 10473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break; 10483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break; 10493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break; 1050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner case AttributeList::AT_transparent_union: 1051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner HandleTransparentUnionAttr(D, Attr, S); 1052803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1053aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; 10549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; 1055803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner default: 1056803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0 1057803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner // TODO: when we have the full set of attributes, warn about unknown ones. 1058803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner S.Diag(Attr->getLoc(), diag::warn_attribute_ignored, 1059803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner Attr->getName()->getName()); 1060803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif 1061803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner break; 1062803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1063803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1064803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1065803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified 1066803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes. 1067803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) { 1068803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner while (AttrList) { 1069803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner ProcessDeclAttribute(D, *AttrList, *this); 1070803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner AttrList = AttrList->getNext(); 1071803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner } 1072803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner} 1073803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 1074803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 10750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in 10760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D. This is a bit tricky because PD can have attributes 10770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all. 10780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) { 10790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Apply decl attributes from the DeclSpec if present. 10800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes()) 10810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 1082803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner 10830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Walk the declarator structure, applying decl attributes that were in a type 10840744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // position to the decl itself. This handles cases like: 10850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // int *__attr__(x)** D; 10860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // when X is a decl attribute. 10870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) 10880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs()) 10890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 10900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 10910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner // Finally, apply any attributes on the decl itself. 10920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner if (const AttributeList *Attrs = PD.getAttributes()) 10930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner ProcessDeclAttributeList(D, Attrs); 10940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner} 10950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner 1096