SemaDeclAttr.cpp revision 0db29ece81d360dcefbe912339c34abe5917f6a9
16b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
26b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
36b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//                     The LLVM Compiler Infrastructure
46b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
56b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// This file is distributed under the University of Illinois Open Source
66b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner// License. See LICENSE.TXT for details.
76b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
86b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
96b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//  This file implements decl-related attribute processing.
116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//
126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner//===----------------------------------------------------------------------===//
136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "Sema.h"
156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner#include "clang/AST/ASTContext.h"
16acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/DeclObjC.h"
17acc5f3e42334525bf28c86471551f83dfce222d5Daniel Dunbar#include "clang/AST/Expr.h"
18fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner#include "clang/Basic/TargetInfo.h"
1912bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Parse/DeclSpec.h"
206e1eb87c04a3acd50888375dad59fac06b7ceb1fTed Kremenek#include <llvm/ADT/StringExtras.h>
216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerusing namespace clang;
226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
23e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
24e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//  Helper functions
25e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
26e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
27d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic const FunctionType *getFunctionType(Decl *d) {
286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType Ty;
296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (ValueDecl *decl = dyn_cast<ValueDecl>(d))
306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *decl = dyn_cast<FieldDecl>(d))
326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getType();
336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d))
346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = decl->getUnderlyingType();
356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else
366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return 0;
376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Ty->isFunctionPointerType())
396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Ty = Ty->getAsPointerType()->getPointeeType();
40d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
41d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return Ty->getAsFunctionType();
426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
443568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
453568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
47d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function
48d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
503568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) {
51d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return getFunctionType(d) || isa<ObjCMethodDecl>(d);
52d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
533568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
54d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
55d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
56d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod.
57d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) {
58d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
59d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return isa<FunctionTypeProto>(FnTy);
60d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  } else {
61d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    assert(isa<ObjCMethodDecl>(d));
62d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
63d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
643568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
653568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
66d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
67d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
68d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
693568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) {
70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
723568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getNumArgs();
733568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
743568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getNumParams();
753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
763568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
773568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
783568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
80d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->getArgType(Idx);
823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
833568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
843568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
863568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
873568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) {
88d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
89d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy);
903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
923568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
933568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
943568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
953568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
97b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const PointerType *PT = T->getAsPointerType();
98b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
101b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
1026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
1036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
1066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
112085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
113085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const PointerType *PT = T->getAsPointerType();
114085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
118085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
119085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
120085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
121085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
122085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (RD->getTagKind() != TagDecl::TK_struct)
123085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
124085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
125085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
128e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
129e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
130e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
131e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1333068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
136803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
137803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
138545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
139545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
140803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
141545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
146545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
1473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
150545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
152803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
153fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
154fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "ext_vector_type" << sizeExpr->getSourceRange();
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
1586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
159b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
160d162584991885ab004a02573a73ce06422b921fcChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType;
1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
1646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
1656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
1666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
168fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
169fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
173803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
175803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
178065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
179065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
180065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
181065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
182065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
183065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
184065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
185065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
186065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
188065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
189065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
194fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
195fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
198065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
199065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
200545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
2013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
202065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
204545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
2056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
206803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
208fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << sizeExpr->getSourceRange();
209065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
2126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
213b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
214b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    assert(0 && "HandleVector(): Complex type construction unimplemented");
2166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
2186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
2196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
2206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
2216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
2256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
2266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
2276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the base type must be integer or float.
229b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
230d162584991885ab004a02573a73ce06422b921fcChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
231065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
233803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
239fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
240fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
241065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
244fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
245fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
246065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
248065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
249065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
250065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
251803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
252065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
253065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
254065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
255065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
256065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
259803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
261545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2623c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
2673b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar    TD->addAttr(new PackedAttr(1));
2686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
272803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
273fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
27408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
2763b0db908ebd07eaa26bc90deba5e826de00fe515Daniel Dunbar      FD->addAttr(new PackedAttr(1));
2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
28196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
28296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
28396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
28596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
28696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
28796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
28896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
28996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
29096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
29196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    ID->addAttr(new IBOutletAttr());
29296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
29396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
29496329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
29596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
296eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
297eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
298eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
299d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
300fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
301026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "nonnull" << 0 /*function*/;
302eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
303eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
304eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
305d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
306eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
307eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
308eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
309eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
313eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
314eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
315f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
318fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
319fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
326fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
32730bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
329eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
330465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
331465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
332eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
333eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
33446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    QualType T = getFunctionOrMethodArgType(d, x);
33546bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    if (!T->isPointerType() && !T->isBlockPointerType()) {
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
337fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
338fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3397fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
340eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
341eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
344eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
3457fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // If no arguments were specified to __attribute__((nonnull)) then all
3467fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // pointer arguments have a nonnull attribute.
3477fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
34846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
34946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
35046bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      if (T->isPointerType() || T->isBlockPointerType())
351d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
35246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
3537fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3547fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3557fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3567fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3577fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3627fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
3637fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  d->addAttr(new NonNullAttr(start, size));
364eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
365eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
368545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
3693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
373545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
378fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
3806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
3876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AliasAttr(std::string(Alias, AliasLen)));
3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
391af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
392af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
393af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
394af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
3953c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
396af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
397af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
398af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
399af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  d->addAttr(new AlwaysInlineAttr());
400af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
401af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
402803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
404545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4053c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
4066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
408d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
409d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d)) {
410fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
411026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "noreturn" << 0 /*function*/;
4126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoReturnAttr());
4166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
41873798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
41973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
42073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
4213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
42273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
42373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
42473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
425d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
426fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
427026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "unused" << 2 /*variable and function*/;
42873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
42973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
43073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
43373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
434b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
435b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
436b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
437b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
438b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
439b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
440b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
441b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
442186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
443b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
444b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
445b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
446b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
447b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
448026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "used" << 2 /*variable and function*/;
449b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
450b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
451b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
452b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  d->addAttr(new UsedAttr());
453b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
454b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4563068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4573068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
458fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
459fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4673068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
468fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
478026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "constructor" << 0 /*function*/;
4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new ConstructorAttr(priority));
4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4843068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4853068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
488fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
489fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4933068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
498fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4993c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
5003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5033068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5043068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5056782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
506fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
507026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "destructor" << 0 /*function*/;
5083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5103068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new DestructorAttr(priority));
5123068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
514803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
516545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
5173c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
524bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
525bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
526bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
527bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
528bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
529bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
530bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
531bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  d->addAttr(new UnavailableAttr());
532bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
533bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
534803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
536545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
5373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
541545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
5436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
546fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5473c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
5586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
5596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
5606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
5616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
5626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
5636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
56408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
5656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5710db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCGCAttr(Decl *D, const AttributeList &Attr, Sema &S) {
5726e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson  if (!Attr.getParameterName()) {
573fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5743c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << 1;
575aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
576aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
577aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
578aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  if (Attr.getNumArgs() != 0) {
5793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
580aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
581aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
5820db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
583aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  ObjCGCAttr::GCAttrTypes type;
58492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("weak")) {
5850db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    if (isa<FieldDecl>(D) && !isa<ObjCIvarDecl>(D))
5862682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
587aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Weak;
5882682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian  }
58992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  else if (Attr.getParameterName()->isStr("strong"))
590aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Strong;
591aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  else {
592fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
5933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << Attr.getParameterName();
594aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
595aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
596aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
5970db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  D->addAttr(new ObjCGCAttr(type));
598aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson}
599aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
6000db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
6010db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
6020db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
6030db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6040db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
6060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
6080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
6090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
6100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
6120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  D->addAttr(new ObjCExceptionAttr());
6140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
6150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
617fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
618fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
619fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
620fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
6210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
622fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
623fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
624fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
625fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
626fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
627fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
628fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
6290db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  D->addAttr(new ObjCNSObjectAttr);
630fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
631fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
632f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void
633f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
634f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
635f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
636f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
637f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
638f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
639f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
640f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
641f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
642f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
643f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
644f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  D->addAttr(new OverloadableAttr);
645f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
646f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
6479eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6489eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (!Attr.getParameterName()) {
649fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
6519eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6549eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
6553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6569eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6599eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
66092e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
6619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
6629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
663fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
6643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
6659eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6689eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  d->addAttr(new BlocksAttr(type));
6699eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
6709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
671770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
672770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
673770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
674fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
675fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
676770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
679770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
680770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
684fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6853c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
690770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
691fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
692fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
694770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
695770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
701770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
702fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7033c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
707770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
708770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
709770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
710770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
711fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
712fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
713770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
716770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
717770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    QualType FT = FD->getType();
719770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
720770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
723770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
724770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
725770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
726770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
727770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
728770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
729fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
730026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "sentinel" << 3 /*function or method*/;
731770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
732770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
734770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // FIXME: Actually create the attribute.
735770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
736770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
737026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
738026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
739026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
740026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
741026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
742026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
743026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
744026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // TODO: could also be applied to methods?
745026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
746026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (!Fn) {
747026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
748026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    << "warn_unused_result" << 0 /*function*/;
749026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
750026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
751026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
752026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  Fn->addAttr(new WarnUnusedResultAttr());
753026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
754026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
755026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
7566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
757545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
762026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  D->addAttr(new WeakAttr());
7636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
765026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
7666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
767545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7717b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
7722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
773026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
774026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    D->addAttr(new DLLImportAttr());
7752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
778026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
7792f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
7802f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
781026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "dllimport" << 2 /*variable and function*/;
7822f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7832f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7842f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7852f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllimport attribute is ignored for inlined functions.
7862f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
7872f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
7882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
7892f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7902f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7912f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7922f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // The attribute is also overridden by a subsequent declaration as dllexport.
7932f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
7942f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
7952f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov       nextAttr = nextAttr->getNext()) {
7962f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
7972f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
7982f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      return;
7992f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    }
8002f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8012f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
802026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (D->getAttr<DLLExportAttr>()) {
8032f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
8042f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8052f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
807026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  D->addAttr(new DLLImportAttr());
8086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
810026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
812545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8172f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
818026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
819026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    D->addAttr(new DLLExportAttr());
8202f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8212f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8222f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
823026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
8242f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
8252f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
826026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "dllexport" << 2 /*variable and function*/;
8272f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8282f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8292f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
8302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllexport attribute is ignored for inlined functions,
8312f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
8322f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
8332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
8342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
8352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8362f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8372f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
838026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  D->addAttr(new DLLExportAttr());
8396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
841026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
84217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
84317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
84417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
84517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
84617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
84717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
84817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
84917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
85017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  StringLiteral *SE =
85117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
85217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
85317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    // FIXME
85417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
85517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
85617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
857026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  D->addAttr(new SectionAttr(std::string(SE->getStrData(),
85817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar                                         SE->getByteLength())));
85917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
86017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
861803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8627b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
863545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8643c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8677b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8687b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute can be applied only to functions.
8697b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
8707b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
871026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "stdcall" << 0 /*function*/;
8727b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8737b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8747b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8757b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
8767b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<FastCallAttr>()) {
8777b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
8787b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "stdcall" << "fastcall";
8797b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8807b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8817b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
8836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
885803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8867b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
887545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8883c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8917b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8927b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
8937b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
894026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "fastcall" << 0 /*function*/;
8957b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8967b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8977b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8987b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
8997b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<StdCallAttr>()) {
9007b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
9017b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "fastcall" << "stdcall";
9027b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
9037b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
9047b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
9066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
908803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
910545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
9113c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9136b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
9166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
918232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
919232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
920232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
9213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
922232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
923232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
924232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
925232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new ConstAttr());
926232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
927232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
928232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
929232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
930232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
9313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
932232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
933232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
934232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
935232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new PureAttr());
936232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
937232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
938f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
93989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // Match gcc which ignores cleanup attrs when compiling C++.
94089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (S.getLangOptions().CPlusPlus)
94189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
94289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
943f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!Attr.getParameterName()) {
944f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
945f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
946f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
947f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
948f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
949f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
950f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
951f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
952f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
953f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
954f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
955f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
956f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
957f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
958f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
959f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
960f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
96147b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
96247b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor                                        Sema::LookupOrdinaryName);
963f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
96489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
965f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
966f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
967f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
968f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
969f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
970f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
97189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
972f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
973f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
974f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
975f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
976f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
97789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
978f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
979f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
980f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
981f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
98289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
98389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
98489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
98589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
98689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (Ty != ParamTy) {
98789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(),
98889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
98989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
99089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
99189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
99289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
993f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  d->addAttr(new CleanupAttr(FD));
994f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
995f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
9976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
998803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1000545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1001fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
10036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1006545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
10073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
10086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1011d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
1012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1013026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "format" << 0 /*function*/;
10146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
10186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
10196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
10203568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
10216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
10226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1023545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
1024545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
10256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
10276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
10286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
10296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
10306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
10316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
10356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
1036085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
10376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
10396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
1040803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1041803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
1042803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
10436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
1044085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1045085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1046085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
10476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
10486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
1051fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1052fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << Attr.getParameterName()->getName();
10536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1057545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1058803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1059803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1060fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10613c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
10626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1066fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
10673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
10726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
10736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
10753568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1077085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
1078085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1079fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1080fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1081085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1082085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
1083085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
10846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
1086803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
10876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
10886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
1089fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1090fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
10916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
10946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
10956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
10966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
1097fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1098fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1103545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1104803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1105803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1106fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
11086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
11126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
11133568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
11146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
11156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1116803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
11176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
11186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
11196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11213c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
11223c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
11236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
11246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1125fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1126fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
11276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
11286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
11296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1131fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
11323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
11336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
11376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
11386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11400b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
11410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1143545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
11443c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1148bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This shouldn't be restricted to typedefs
1149bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1150bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
1151fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1152026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "transparent_union" << 1 /*union*/;
11536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1156bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1157bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
1158bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: Should we do a check for RD->isDefinition()?
1159bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
1160bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
1161bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // we might silently generate incorrect code; see following code
116244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  for (RecordDecl::field_iterator Field = RD->field_begin(),
116344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor                               FieldEnd = RD->field_end();
116444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Field != FieldEnd; ++Field) {
116544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (!Field->getType()->isPointerType()) {
1166bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
1167bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1168bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1169bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
11706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1171bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This is a complete hack; we should be properly propagating
1172bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // transparent_union through Sema.  That said, this is close enough to
1173bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // correctly compile all the common cases of transparent_union without
1174bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // errors or warnings
1175bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  QualType NewTy = S.Context.VoidPtrTy;
1176bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  NewTy.addConst();
1177bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TD->setUnderlyingType(NewTy);
11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1182545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1186545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
11876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
11906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
11916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
11920b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1199803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1201545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
12023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1207545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
12096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
12106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
121349e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
121449e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
121549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1216803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1217fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1218fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
121949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
122049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
122149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
12226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1223fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
12240b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
1225065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
1226fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1227fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
1228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1229fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
1230fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
12310b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1232fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1233fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1234fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1235fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1236fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
12373c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1241fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1242fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
12430b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1244fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1245fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1246fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
1247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
1248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1249fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1250fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
1253fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
1254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1255fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
1258fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
1259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
1260fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
1261fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
1262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
1263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
1264fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
1265fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
1266fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
1267fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
1268fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
1269fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1270fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1271fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1272fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1273fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
12740b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1275fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
12760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1277fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1279fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
12800b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1281fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1282fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1283fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1285fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1286fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1287fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1288fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1289fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1290fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1291fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1293fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1294fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1295f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1296f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // int8_t and friends, at least with glibc.
1297f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1298f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // the wrong width on unusual platforms.
1299f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1300f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1303fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
13043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1305fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1306fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
13073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1308fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1309fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
1310fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1311fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
13120b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1313fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
13140b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1315fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1316fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
1317fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1318fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
13190b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1320fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
13210b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1322fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1323fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1324fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
13250b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1326fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
13270b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1328fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
13290b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1330fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1331fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1332fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
13330b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1334fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
13350b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1336fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
13370b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1338fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1339f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1340f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1341f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1342f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1343f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1344f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1345fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1346fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1347fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
13480b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1349fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1350fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
13510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1353fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1354fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1355fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1356fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1357fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1358fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1359fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
13600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1361d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1362d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1363d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1364d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1365d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1366d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1367e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
1368e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson  if (!isa<FunctionDecl>(d)) {
1369d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1370026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner      << "nodebug" << 0 /*function*/;
1371d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1372d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1373d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
1374d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  d->addAttr(new NodebugAttr());
1375d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1376d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
13770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
13780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
13790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
13800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1381a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1382803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1383803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1384803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1385803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
13863068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1387803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1388803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1389803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1390803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
13913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1392af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  case AttributeList::AT_always_inline:
1393af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
13943068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
13953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1396803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
13973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1398803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
13993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
14003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
14013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
14023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1403803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1404803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
14053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1406eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
14073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
14083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
14093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
141017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
14113068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1412bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
141373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1414b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
14153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
14163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1417026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1418026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
14193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1420803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1421803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1422803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1423aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
14240db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
14250db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
14260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
1427f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1428fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
14299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1430770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1431232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1432232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1433f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1434d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
143505f8e471aae971c9867dbac148eba1275a570814Anders Carlsson  case AttributeList::IgnoredAttribute:
143605f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
143705f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
1438803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1439d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1440803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1441803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1442803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1443803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1444803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1445803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
1446803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1447803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
1448803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
1449803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1450803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1451803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1452803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1453803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
14540744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
14550744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
14560744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
14570744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
14580744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
14590744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
14600744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
1461803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
14620744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
14630744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
14640744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
14650744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
14660744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
14670744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
14680744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
14690744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
14700744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
14710744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
14720744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
14730744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
14740744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1475