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