SemaDeclAttr.cpp revision 3c73c41cefcfe76f36b7bed72c9f1ec195490951
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h"
156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
18e4858a65a93fb36c099d8dd2ea0a98e33e77687eDaniel Dunbar#include "clang/Basic/Diagnostic.h"
19fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
2012bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h"
216e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h>
226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
27e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
28d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic const FunctionType *getFunctionType(Decl *d) {
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = Ty->getAsPointerType()->getPointeeType();
41d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
42d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return Ty->getAsFunctionType();
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
453568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
48d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function
49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
513568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) {
52d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return getFunctionType(d) || isa<ObjCMethodDecl>(d);
53d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
543568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
55d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
56d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod.
58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) {
59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
60d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return isa<FunctionTypeProto>(FnTy);
61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  } else {
62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    assert(isa<ObjCMethodDecl>(d));
63d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
64d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
69d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
703568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) {
71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
72d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getNumArgs();
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getNumParams();
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
793568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
80d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
81d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getArgType(Idx);
833568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
843568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
883568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) {
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
90d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
933568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
943568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
963568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const PointerType *PT = T->getAsPointerType();
99b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
102b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
1076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
114085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const PointerType *PT = T->getAsPointerType();
115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
119085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
120085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
121085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
122085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
123085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (RD->getTagKind() != TagDecl::TK_struct)
124085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
125085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
128085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
129e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
130e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
131e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
132e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
137803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
138803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
140545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
142545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
147545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
1483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
151545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
153803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
154fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
155fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "ext_vector_type" << sizeExpr->getSourceRange();
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
1596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
160b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
161fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type)
162fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << curType.getAsString();
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
170fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
171fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
177803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
184065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
187065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
189803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
195065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
196fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
197fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
198065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
199065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
200065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
201065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
202545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
2033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
204065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
206545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
2076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
208803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
209fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
210fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << sizeExpr->getSourceRange();
211065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
2146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
215b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
216b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    assert(0 && "HandleVector(): Complex type construction unimplemented");
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the base type must be integer or float.
231b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
232fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type)
233fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << CurType.getAsString();
234065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
236803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
2396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
2416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
242fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
243fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
244065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
247fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
248fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
249065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
251065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
252065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
253065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
254803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
255065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
256065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
257065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
258065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
259065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
262803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
264545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2653c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
2703b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar    TD->addAttr(new PackedAttr(1));
2716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
275803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
276fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
2773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << Attr.getName() << FD->getType().getAsString();
2786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
2793b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar      FD->addAttr(new PackedAttr(1));
2806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
28596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2873c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
29196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
29296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
29396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
29496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    ID->addAttr(new IBOutletAttr());
29596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
29696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
29796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
29896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
299eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
300eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
301eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
302d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
303fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
304fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "nonnull" << "function";
305eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
308d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
315eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    Expr *Ex = static_cast<Expr *>(Attr.getArg(0));
319eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
321fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
322fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
329fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
33030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
333465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
334465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
33746bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    QualType T = getFunctionOrMethodArgType(d, x);
33846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    if (!T->isPointerType() && !T->isBlockPointerType()) {
339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
340fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
341fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3427fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
345eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
3487fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // If no arguments were specified to __attribute__((nonnull)) then all
3497fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // pointer arguments have a nonnull attribute.
3507fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
35146bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
35246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
35346bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      if (T->isPointerType() || T->isBlockPointerType())
354d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
35546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3587fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
361eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3647fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3657fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
3667fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  d->addAttr(new NonNullAttr(start, size));
367eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
368eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
369803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
371545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
3723c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
376545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
381fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
394af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
395af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
396af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
397af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
3983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
399af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
400af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
401af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
402af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  d->addAttr(new AlwaysInlineAttr());
403af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
404af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
405803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
407545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
4096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
411d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
412d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d)) {
413fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
414fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "noreturn" << "function";
4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
4196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
42173798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
42373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
4243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
42573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
42673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
42773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
428d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
429fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
430fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "unused" << "variable and function";
43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
43373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
43473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
43573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
43673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
4373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
440fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
441fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
450fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
459fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
460fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "constructor" << "function";
4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new ConstructorAttr(priority));
4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
470fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
471fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4773068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4783068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
480fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4876782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
488fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
489fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "destructor" << "function";
4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new DestructorAttr(priority));
4943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
496803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
498545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4993c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
5046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
506803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
508545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
5093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
5106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
513545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
5166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
518fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
5256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
5266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
536fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
537fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "visibility" << TypeStr;
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
544aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5456e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson  if (!Attr.getParameterName()) {
546fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << 1;
548aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
549aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
550aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
551aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  if (Attr.getNumArgs() != 0) {
5523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
553aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  ObjCGCAttr::GCAttrTypes type;
5583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  if (Attr.getParameterName()->isName("weak"))
559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Weak;
5603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  else if (Attr.getParameterName()->isName("strong"))
561aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Strong;
562aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  else {
563fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
5643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << Attr.getParameterName();
565aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
566aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
567aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
568aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  d->addAttr(new ObjCGCAttr(type));
569aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson}
570aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
5719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (!Attr.getParameterName()) {
573fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
5759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5769eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5779eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5789eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
5793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
5809eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5819eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5839eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
5843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  if (Attr.getParameterName()->isName("byref"))
5859eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
5869eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
587fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
5883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
5899eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
5909eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
5919eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
5929eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  d->addAttr(new BlocksAttr(type));
5939eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
5949eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
595770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
596770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
597770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
598fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
599fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
600770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
601770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
602770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
603770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
604770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
605770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
606770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
607770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
608fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
610770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
611770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
612770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
613770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
614770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
615fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
616fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
617770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
618770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
619770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
620770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
621770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
622770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
623770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
624770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
625770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
626fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6273c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
628770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
629770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
630770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
631770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
632770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
633770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
634770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
635fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
636fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
637770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
638770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
639770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
640770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
641770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
642770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    QualType FT = FD->getType();
643770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
644770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
645770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
646770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
647770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
648770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
649770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
650770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
651770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
652770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
653fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
654fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "sentinel" << "function or method";
655770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
656770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
657770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
658770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // FIXME: Actually create the attribute.
659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
661803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
663545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
6696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
671803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
673545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
6796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
681803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
683545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
6896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
691803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
693545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
6943c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
6996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
703545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
713545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
7196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
721232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
722232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
723232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
7243c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
725232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
726232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
727232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
728232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new ConstAttr());
729232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
730232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
731232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
732232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
733232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
7343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
735232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
736232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
737232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
738232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new PureAttr());
739232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
740232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
7416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
7426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
743803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
745545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
746fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
7473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
7486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
751545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
7523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
756d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
757fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
758fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << "function";
7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
7636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
7646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
7653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
7666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
7676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
768545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
769545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
7706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
7726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
7736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
7746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
7756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
7766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
7796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
7806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
781085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
7826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
785803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
786803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
787803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
7886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
789085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
790085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
791085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
7926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
7936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
796fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
797fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << Attr.getParameterName()->getName();
7986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
802545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
803803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
804803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
805fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
8063c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
8076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
811fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
8123c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
8136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
8176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
8186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
8203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
8216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
822085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
823085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
824fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
825fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
826085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
827085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
828085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
8296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
8306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
8326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
8336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
834fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
835fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
8366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
8376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
8386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
8396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
8416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
842fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
843fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
8446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
848545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
849803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
850803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
851fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
8523c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
8576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
8583568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
8626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
8636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
8646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8663c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
8673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
8686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
8696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
870fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
871fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
8726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
8736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
8746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
8756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
876fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
8773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
8786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
8860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
8876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
888545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
893bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This shouldn't be restricted to typedefs
894bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
895bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
896fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
897fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "transparent_union" << "union";
8986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
901bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
902bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
903bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: Should we do a check for RD->isDefinition()?
904bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
905bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
906bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // we might silently generate incorrect code; see following code
907bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  for (int i = 0; i < RD->getNumMembers(); i++) {
908bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    if (!RD->getMember(i)->getType()->isPointerType()) {
909bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
910bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
911bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
912bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
9136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
914bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This is a complete hack; we should be properly propagating
915bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // transparent_union through Sema.  That said, this is close enough to
916bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // correctly compile all the common cases of transparent_union without
917bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // errors or warnings
918bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  QualType NewTy = S.Context.VoidPtrTy;
919bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  NewTy.addConst();
920bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TD->setUnderlyingType(NewTy);
9216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
925545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
9263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
929545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
9306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
9316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
9336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
9346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
9350b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
9366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
9396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
9406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
942803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
944545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
9453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
9466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
950545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
9516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
9526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
9536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
9546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
95649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
95749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
95849e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
959803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
960fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
961fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
96249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
96349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
96449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
9656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
966fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
9670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
968065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
969fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
970fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
971fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
972fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
973fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
9740b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
975fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
976fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
977fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
978fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
979fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
9803c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
981fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
982fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
983fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
984fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
985fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
9860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
987fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
988fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
989fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
990fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
991fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
992fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
993fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
994fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
995fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
996fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
997fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
998fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
999fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1000fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
1001fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
1002fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
1003fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
1004fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
1005fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
1006fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
1007fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
1008fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
1009fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
1010fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
1011fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
1012fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1013fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1014fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1015fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1016fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
10170b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1018fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
10190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1020fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1021fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1022fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
10230b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1024fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1025fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1026fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1027fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1028fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1029fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1030fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1031fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1032fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1033fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1034fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1035fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1036fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1037fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1038fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // FIXME: Need proper fixed-width types
1039fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1040fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1041fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
10423c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1043fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1044fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
10453c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1046fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1047fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
1048fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1049fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
10500b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1051fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
10520b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1053fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1054fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
1055fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1056fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
10570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1058fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
10590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1060fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1061fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1062fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
10630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1064fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
10650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1066fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
10670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1068fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1069fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1070fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
10710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1072fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
10730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1074fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
10750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1076fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1077fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1078fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1079fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
10800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1081fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1082fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
10830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1084fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1085fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1086fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1087fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1088fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1089fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1090fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1091fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
10920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
10930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
10940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
10950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
10960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1097803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// HandleDeclAttribute - Apply the specific attribute to the specified decl if
1098803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1099803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1100803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1101803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
11023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1103803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1104803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1105803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1106803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
11073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1108af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  case AttributeList::AT_always_inline:
1109af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
11103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
11113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1112803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
11133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1114803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
11153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
11163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
11173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
11183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1119803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1120803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
11213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1122eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
11233068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
11243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
11253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
11263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
112773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
11283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
11293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
11303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1131803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1132803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1133803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1134aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
11359eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1136770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1137232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1138232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1139803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
1141803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
1142fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored)
1143fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        <<  Attr->getName()->getName();
1144803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
1145803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1146803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1147803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1148803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1149803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1150803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
1151803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1152803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
1153803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
1154803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1155803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1156803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1157803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1158803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
11590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
11600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
11610744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
11620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
11630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
11640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
11650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
1166803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
11670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
11680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
11690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
11700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
11710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
11720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
11730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
11740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
11750744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
11760744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
11770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
11780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
11790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1180