SemaDeclAttr.cpp revision f98aba35e6c3da5aae61843fc01334939e4e12ec
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)
301fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "nonnull" << "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)
411fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "noreturn" << "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)
427fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "unused" << "variable and function";
42873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
42973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
43073798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
43173798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  d->addAttr(new UnusedAttr());
43273798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
43373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
4343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
437fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
438fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
4393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
447fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
4493068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4503068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4513068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4533068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
4553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (!Fn) {
456fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
457fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "constructor" << "function";
4583068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4593068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4603068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4613068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new ConstructorAttr(priority));
4623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4633068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4653068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4663068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
467fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
468fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
4693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4703068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4713068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4733068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
4743068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
4753068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
4763068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
477fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
4783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
4793068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
4803068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
4813068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
4823068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4833068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4846782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
485fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
486fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "destructor" << "function";
4873068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4883068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4893068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  d->addAttr(new DestructorAttr(priority));
4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
493803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
495545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4963c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
4976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
4986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DeprecatedAttr());
5016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
503bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
504bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
505bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
506bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
507bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
508bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
509bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
510bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  d->addAttr(new UnavailableAttr());
511bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
512bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
513803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
515545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
5163c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
5176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
520545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
5216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
5226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
5236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
525fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
5276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
5316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
5326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
5336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
5356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
5366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
5376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
5386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
5396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
5406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
5416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
5426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
54308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
5446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new VisibilityAttr(type));
5486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
550aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlssonstatic void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5516e14a8f2ac4af8e3741eac8e9dccec0061bc7166Anders Carlsson  if (!Attr.getParameterName()) {
552fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << 1;
554aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
555aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
556aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
557aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  if (Attr.getNumArgs() != 0) {
5583c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
559aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
560aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
561aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
562aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
563aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  ObjCGCAttr::GCAttrTypes type;
56492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("weak")) {
56524b93f2debe1fdb98c7b03a79486a02bf8b9c9e4Fariborz Jahanian    if (isa<FieldDecl>(d) && !isa<ObjCIvarDecl>(d))
5662682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
567aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Weak;
5682682d8b3a0415d521d5ca11afb13a8bc5c559a31Fariborz Jahanian  }
56992e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  else if (Attr.getParameterName()->isStr("strong"))
570aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    type = ObjCGCAttr::Strong;
571aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  else {
572fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
5733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "objc_gc" << Attr.getParameterName();
574aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson    return;
575aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  }
576aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
577aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  d->addAttr(new ObjCGCAttr(type));
578aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson}
579aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson
580fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanianstatic void HandleObjCNSObject(Decl *d, const AttributeList &Attr, Sema &S) {
581fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
582fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
583fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
584fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
585fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(d)) {
586fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
587fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
588fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
589fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
590fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
591fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
592fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
593fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  d->addAttr(new ObjCNSObjectAttr);
594fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
595fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
596f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void
597f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
598f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
599f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
600f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
601f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
602f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
603f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
604f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
605f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
606f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
607f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
608f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  D->addAttr(new OverloadableAttr);
609f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
610f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
6119eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6129eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (!Attr.getParameterName()) {
613fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
6159eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6169eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6179eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6189eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
6193c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6209eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6219eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6229eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6239eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
62492e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
6259eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
6269eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
627fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
6283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
6299eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6309eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6319eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6329eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  d->addAttr(new BlocksAttr(type));
6339eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
6349eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
635770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
636770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
637770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
638fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
639fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
640770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
641770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
642770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
643770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
644770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
645770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
646770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
647770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
648fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6493c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
650770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
651770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
652770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
653770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
654770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
655fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
656fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
657770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
658770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
659770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
660770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
661770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
662770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
663770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
664770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
665770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
666fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
668770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
669770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
670770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
671770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
672770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
673770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
674770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
675fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
676fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
679770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
680770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    QualType FT = FD->getType();
683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
684770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
685770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
689770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
690770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
691770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
693fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
694fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "sentinel" << "function or method";
695770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
696770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
697770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // FIXME: Actually create the attribute.
699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
703545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
7086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new WeakAttr());
7096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
711803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLImportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
713545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7143c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7177b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
7182f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
7192f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (isa<VarDecl>(d)) {
7202f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    d->addAttr(new DLLImportAttr());
7212f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7222f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7232f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7242f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
7252f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
7262f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
7272f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      << "dllimport" << "function or variable";
7282f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7292f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7302f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7312f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllimport attribute is ignored for inlined functions.
7322f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
7332f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
7342f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
7352f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7362f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7372f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7382f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // The attribute is also overridden by a subsequent declaration as dllexport.
7392f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
7402f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
7412f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov       nextAttr = nextAttr->getNext()) {
7422f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
7432f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
7442f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      return;
7452f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    }
7462f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7482f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (d->getAttr<DLLExportAttr>()) {
7492f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
7502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7512f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7522f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLImportAttr());
7546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
756803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDLLExportAttr(Decl *d, const AttributeList &Attr, Sema &S) {
7576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
758545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7627b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
7632f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
7642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (isa<VarDecl>(d)) {
7652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    d->addAttr(new DLLExportAttr());
7662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7672f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7682f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7692f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  FunctionDecl *FD = dyn_cast<FunctionDecl>(d);
7702f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
7712f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
7722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      << "dllexport" << "function or variable";
7732f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7742f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllexport attribute is ignored for inlined functions,
7772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
7782f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
7792f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
7802f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
7812f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
7822f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
7832f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
7846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new DLLExportAttr());
7856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
7866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
78717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbarstatic void HandleSectionAttr(Decl *d, const AttributeList &Attr, Sema &S) {
78817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
78917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
79017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
79117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
79217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
79317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
79417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
79517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
79617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  StringLiteral *SE =
79717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
79817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
79917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    // FIXME
80017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
80117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
80217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
80317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  d->addAttr(new SectionAttr(std::string(SE->getStrData(),
80417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar                                         SE->getByteLength())));
80517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
80617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
807803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8087b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
809545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8103c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8137b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8147b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute can be applied only to functions.
8157b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
8167b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8177b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "stdcall" << "function";
8187b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8197b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8207b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8217b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
8227b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<FastCallAttr>()) {
8237b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
8247b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "stdcall" << "fastcall";
8257b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8267b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8277b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new StdCallAttr());
8296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
831803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8327b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
833545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8343c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8377b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8387b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
8397b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8407b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "fastcall" << "function";
8417b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8427b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8437b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
8457b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<StdCallAttr>()) {
8467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
8477b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "fastcall" << "stdcall";
8487b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
8497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
8507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FastCallAttr());
8526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
854803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
8556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
856545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8573c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8596b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new NoThrowAttr());
8626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
864232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
865232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
866232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
8673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
868232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
869232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
870232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
871232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new ConstAttr());
872232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
873232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
874232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
875232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
876232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
8773c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
878232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
879232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
880232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
881232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  d->addAttr(new PureAttr());
882232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
883232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
884f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
88589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // Match gcc which ignores cleanup attrs when compiling C++.
88689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (S.getLangOptions().CPlusPlus)
88789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
88889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
889f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!Attr.getParameterName()) {
890f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
891f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
892f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
893f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
894f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
895f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
896f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
897f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
898f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
899f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
900f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
901f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
902f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
903f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
904f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
905f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
906f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
90747b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
90847b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor                                        Sema::LookupOrdinaryName);
909f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
91089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
911f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
912f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
913f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
914f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
915f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
916f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
91789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
918f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
919f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
920f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
921f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
922f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
92389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
924f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
925f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
926f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
927f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
92889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
92989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
93089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
93189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
93289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (Ty != ParamTy) {
93389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(),
93489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
93589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
93689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
93789941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
93889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
939f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  d->addAttr(new CleanupAttr(FD));
940f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
941f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
9426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
9436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
944803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
946545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
947fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
9483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
9496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
952545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
9533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
9546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
957d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
958fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
959fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << "function";
9606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
9646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
9656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
9663568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
9676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
9686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
969545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
970545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
9716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
9736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
9746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
9756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
9766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
9776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
9806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
9816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
982085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
9836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
9856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
986803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
987803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
988803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
9896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
990085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
991085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
992085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
9936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
9946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
997fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
998fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << Attr.getParameterName()->getName();
9996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1003545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1004803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1005803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1006fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10073c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
10086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1012fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
10133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
10146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
10186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
10196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
10213568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
10226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1023085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
1024085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1025fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1026fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1027085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1028085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
1029085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
10306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: do we need to check if the type is NSString*?  What are
10316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    //  the semantics?
1032803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
10336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // FIXME: Should highlight the actual expression that has the
10346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      // wrong type.
1035fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1036fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
10376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
10386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
10396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
10406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
10416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: Should highlight the actual expression that has the
10426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // wrong type.
1043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1044fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
10456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1049545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1050803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1051803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1052fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
10533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
10546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
10586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
10593568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
10606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
10616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1062803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
10636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
10646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
10656b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10666b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10673c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
10683c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
10696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
10706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1071fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1072fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
10736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
10746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1077fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
10783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
10796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new FormatAttr(std::string(Format, FormatLen),
10836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
10846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10860b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
10870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
10886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1089545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
10903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
10916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1094bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This shouldn't be restricted to typedefs
1095bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
1096bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  if (!TD || !TD->getUnderlyingType()->isUnionType()) {
1097fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
1098fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "transparent_union" << "union";
10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1102bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  RecordDecl* RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
1103bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
1104bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: Should we do a check for RD->isDefinition()?
1105bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
1106bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This isn't supposed to be restricted to pointers, but otherwise
1107bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // we might silently generate incorrect code; see following code
110844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  for (RecordDecl::field_iterator Field = RD->field_begin(),
110944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor                               FieldEnd = RD->field_end();
111044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Field != FieldEnd; ++Field) {
111144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (!Field->getType()->isPointerType()) {
1112bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      S.Diag(Attr.getLoc(), diag::warn_transparent_union_nonpointer);
1113bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1114bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1115bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
11166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1117bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // FIXME: This is a complete hack; we should be properly propagating
1118bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // transparent_union through Sema.  That said, this is close enough to
1119bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // correctly compile all the common cases of transparent_union without
1120bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  // errors or warnings
1121bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  QualType NewTy = S.Context.VoidPtrTy;
1122bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  NewTy.addConst();
1123bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TD->setUnderlyingType(NewTy);
11246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1128545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
11293c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1132545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
11336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
11346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
11376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
11380b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  d->addAttr(new AnnotateAttr(std::string(SE->getStrData(),
11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                                          SE->getByteLength())));
11436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1145803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
11466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1147545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
11483c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
11496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1153545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
11546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
11556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // (For now we just use 128 bits which is the maximum on X86.
11566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
11576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11586b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
115949e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
116049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
116149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1162803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1163fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1164fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
116549e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
116649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
116749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  d->addAttr(new AlignedAttr(Alignment.getZExtValue() * 8));
11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1169fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
11700b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
1171065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
1172fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1173fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
1174fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1175fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
1176fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
11770b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1178fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1179fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1180fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1181fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1182fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
11833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1184fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1185fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1186fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1187fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1188fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
11890b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1190fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1191fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1192fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
1193fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
1194fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1195fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1196fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1197fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1198fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
1199fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
1200fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1201fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1202fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1203fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
1204fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
1205fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
1206fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "QI", 2)) { DestWidth =  8; break; }
1207fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "HI", 2)) { DestWidth = 16; break; }
1208fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SI", 2)) { DestWidth = 32; break; }
1209fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DI", 2)) { DestWidth = 64; break; }
1210fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TI", 2)) { DestWidth = 128; break; }
1211fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "SF", 2)) { DestWidth = 32; IntegerMode = false; break; }
1212fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "DF", 2)) { DestWidth = 64; IntegerMode = false; break; }
1213fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
1214fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }
1215fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1216fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1217fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1218fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1219fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
12200b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1221fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
12220b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1223fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1224fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1225fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
12260b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1227fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1228fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1229fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1230fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1231fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1232fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1233fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1234fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1235fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1236fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1237fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1238fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1239fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1240fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1241f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Sync this with InitializePredefinedMacros; we need to match
1242f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // int8_t and friends, at least with glibc.
1243f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure 32/64-bit integers don't get defined to types of
1244f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // the wrong width on unusual platforms.
1245f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1246f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1247fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1248fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1249fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
12503c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1251fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1252fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
12533c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1254fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1255fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
1256fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1257fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
12580b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1259fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
12600b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1261fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1262fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
1263fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    assert(IntegerMode);
1264fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
12650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1266fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
12670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1268fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1269fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1270fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
12710b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1272fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
12730b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1274fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
12750b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1276fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1277fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1278fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
12790b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1280fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
12810b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1282fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
12830b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1284fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1285f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1286f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1287f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1288f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1289f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1290f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
1291fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1292fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1293fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!OldTy->getAsBuiltinType())
12940b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
1295fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (!(IntegerMode && OldTy->isIntegerType()) &&
1296fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner           !(!IntegerMode && OldTy->isFloatingType())) {
12970b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
1298fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1299fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1300fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1301fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1302fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1303fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1304fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1305fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
13060744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
13070744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
13080744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
13090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
13100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1311a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1312803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1314803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1315803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
13163068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1317803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1318803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // Ignore this, this is a type attribute, handled by ProcessTypeAttributes.
1319803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1320803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
13213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1322af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  case AttributeList::AT_always_inline:
1323af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
13243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
13253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1326803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
13273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1328803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
13293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
13303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
13313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
13323068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1333803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1334803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
13353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
13373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
13383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
13393068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
134017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
13413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1342bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
134373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
13443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
13453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
13463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
1347803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1348803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1349803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1350aa0d25b44e510a5a62e7345f4fa3840a886841d2Anders Carlsson  case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
1351f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1352fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
13539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1354770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1355232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1356232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1357f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1358803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1359803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#if 0
1360803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    // TODO: when we have the full set of attributes, warn about unknown ones.
136108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr->getLoc(), diag::warn_attribute_ignored) << Attr->getName();
1362803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner#endif
1363803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1364803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1365803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1366803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1367803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1368803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
1369803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1370803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
1371803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
1372803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1373803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1374803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1375803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1376803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
13770744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
13780744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
13790744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
13800744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
13810744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
13820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
13830744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
1384803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
13850744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
13860744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
13870744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
13880744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
13890744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
13900744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
13910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
13920744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
13930744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
13940744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
13950744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
13960744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
13970744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1398