SemaDeclAttr.cpp revision 755f9d2c65f75d539a2440e5de82d881e4417397
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
27755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanianstatic const FunctionType *getFunctionType(Decl *d, bool blocksToo = true) {
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();
40755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  else if (blocksToo && Ty->isBlockPointerType())
41620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    Ty = Ty->getAsBlockPointerType()->getPointeeType();
42d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
43d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  return Ty->getAsFunctionType();
446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// FIXME: We should provide an abstraction around a method or function
473568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar// to provide the following bits of information.
483568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
49d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// isFunctionOrMethod - Return true if the given decl has function
50d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// type (function or function-typed variable) or an Objective-C
51d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// method.
523568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethod(Decl *d) {
53755f9d2c65f75d539a2440e5de82d881e4417397Fariborz Jahanian  return getFunctionType(d, false) || isa<ObjCMethodDecl>(d);
54d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar}
553568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
56620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethodOrBlock - Return true if the given decl has function
57620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// type (function or function-typed variable) or an Objective-C
58620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// method or a block.
59620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanianstatic bool isFunctionOrMethodOrBlock(Decl *d) {
60620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (isFunctionOrMethod(d))
61620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return true;
62620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  // check for block is more involved.
63620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
64620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    QualType Ty = V->getType();
65620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian    return Ty->isBlockPointerType();
66620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  }
67620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  return false;
68620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian}
69620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
70d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto - Return true if the given decl has a argument
71d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// information. This decl should have already passed
72620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
73d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbarstatic bool hasFunctionProto(Decl *d) {
74620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (const FunctionType *FnTy = getFunctionType(d))
7572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return isa<FunctionProtoType>(FnTy);
76620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  else {
77d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    assert(isa<ObjCMethodDecl>(d));
78d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar    return true;
79d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  }
803568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
813568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
82d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// getFunctionOrMethodNumArgs - Return number of function or method
83d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// arguments. It is an error to call this on a K&R function (use
84d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar/// hasFunctionProto first).
853568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic unsigned getFunctionOrMethodNumArgs(Decl *d) {
8689951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
8772564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getNumArgs();
8889951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_size();
893568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
903568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
9289951a86b594513c2a013532ed45d197413b1087Chris Lattner  if (const FunctionType *FnTy = getFunctionType(d))
9372564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
9489951a86b594513c2a013532ed45d197413b1087Chris Lattner
95620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian
9689951a86b594513c2a013532ed45d197413b1087Chris Lattner  return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
973568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
983568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
993568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbarstatic bool isFunctionOrMethodVariadic(Decl *d) {
100d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (const FunctionType *FnTy = getFunctionType(d)) {
10172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
1023568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return proto->isVariadic();
1033568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  } else {
1043568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    return cast<ObjCMethodDecl>(d)->isVariadic();
1053568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  }
1063568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar}
1073568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar
1086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattnerstatic inline bool isNSStringType(QualType T, ASTContext &Ctx) {
109b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const PointerType *PT = T->getAsPointerType();
110b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!PT)
1116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1126b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
113b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  const ObjCInterfaceType *ClsT =PT->getPointeeType()->getAsObjCInterfaceType();
1146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!ClsT)
1156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return false;
1166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier();
1186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Should we walk the chain of classes?
1206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  return ClsName == &Ctx.Idents.get("NSString") ||
1216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner         ClsName == &Ctx.Idents.get("NSMutableString");
1226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
124085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbarstatic inline bool isCFStringType(QualType T, ASTContext &Ctx) {
125085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const PointerType *PT = T->getAsPointerType();
126085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!PT)
127085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
128085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
129085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordType *RT = PT->getPointeeType()->getAsRecordType();
130085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (!RT)
131085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
132085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
133085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  const RecordDecl *RD = RT->getDecl();
134085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (RD->getTagKind() != TagDecl::TK_struct)
135085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    return false;
136085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
137085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
138085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar}
139085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar
140e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
141e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner// Attribute Implementations
142e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner//===----------------------------------------------------------------------===//
143e5c5ee1cff9ec084f176fa252774262677857ad2Chris Lattner
1443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// FIXME: All this manual attribute parsing code is gross. At the
1453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// least add some helper functions to check most argument patterns (#
1463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar// and types of args).
1473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
148803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleExtVectorTypeAttr(Decl *d, const AttributeList &Attr,
149803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner                                    Sema &S) {
150545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  TypedefDecl *tDecl = dyn_cast<TypedefDecl>(d);
151545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (tDecl == 0) {
152803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
153545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner    return;
1546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  QualType curType = tDecl->getUnderlyingType();
1576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
158545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
1593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
162545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
1636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
164803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
165fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "ext_vector_type" << sizeExpr->getSourceRange();
1676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, we do not allow vectors to be defined
1706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // in conjunction with complex types (pointers, arrays, functions, etc.).
171b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (!curType->isIntegerType() && !curType->isRealFloatingType()) {
172d162584991885ab004a02573a73ce06422b921fcChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << curType;
1736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // unlike gcc's vector_size attribute, the size is specified as the
1766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // number of elements, not the number of bytes.
1776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
1786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
180fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
181fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
1826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
1836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Instantiate/Install the vector type, the number of elements is > 0.
185803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  tDecl->setUnderlyingType(S.Context.getExtVectorType(curType, vectorSize));
1866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Remember this typedef decl, we will need it later for diagnostics.
187803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  S.ExtVectorDecls.push_back(tDecl);
1886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
190065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
191065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// HandleVectorSizeAttribute - this attribute is only applicable to
192065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// integral and float scalars, although arrays, pointers, and function
193065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// return values are allowed in conjunction with this construct. Aggregates
194065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// with this attribute are invalid, even if they are of the same size as a
195065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// corresponding scalar.
196065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// The raw attribute should contain precisely 1 argument, the vector size
197065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// for the variable, measured in bytes. If curType and rawAttr are well
198065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// formed, this routine will return a new vector type.
199803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVectorSizeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
200065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  QualType CurType;
201065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
202065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = VD->getType();
203065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
204065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    CurType = TD->getUnderlyingType();
205065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else {
206fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
207fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << SourceRange(Attr.getLoc(), Attr.getLoc());
208065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
209065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  }
210065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
211065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Check the attribute arugments.
212545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
2133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
214065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
216545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *sizeExpr = static_cast<Expr *>(Attr.getArg(0));
2176b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  llvm::APSInt vecSize(32);
218803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!sizeExpr->isIntegerConstantExpr(vecSize, S.Context)) {
219fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
220fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "vector_size" << sizeExpr->getSourceRange();
221065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2226b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2236b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // navigate to the base type - we need to provide for vector pointers,
2246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vector arrays, and functions returning vectors.
225b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner  if (CurType->isPointerType() || CurType->isArrayType() ||
226b77792eabf5882cf9af8cc810599b20432fda6c2Chris Lattner      CurType->isFunctionType()) {
2272db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_vector_size) << CurType;
2282db15bdd945163eacfa4623fd2e32a536ed2dd3bChris Lattner    return;
2296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    /* FIXME: rebuild the type from the inside out, vectorizing the inner type.
2306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     do {
2316b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     if (PointerType *PT = dyn_cast<PointerType>(canonType))
2326b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = PT->getPointeeType().getTypePtr();
2336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
2346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = AT->getElementType().getTypePtr();
2356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
2366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType = FT->getResultType().getTypePtr();
2376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     } while (canonType->isPointerType() || canonType->isArrayType() ||
2386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     canonType->isFunctionType());
2396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner     */
2406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
24182afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner  // the base type must be integer or float, and can't already be a vector.
24282afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner  if (CurType->isVectorType() ||
24382afa2d97d39cc0d5a4897716ec0a80aeab9e14bChris Lattner      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
244d162584991885ab004a02573a73ce06422b921fcChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
245065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2466b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
247803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
2486b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // vecSize is specified in bytes - convert to bits.
2496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8);
2506b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the vector size needs to be an integral multiple of the type size.
2526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize % typeSize) {
253fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
254fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
255065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (vectorSize == 0) {
258fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_zero_size)
259fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << sizeExpr->getSourceRange();
260065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    return;
2616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
262065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
263065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // Success! Instantiate the vector type, the number of elements is > 0, and
264065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  // not required to be a power of 2, unlike GCC.
265803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);
266065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner
267065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
268065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    VD->setType(CurType);
269065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner  else
270065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner    cast<TypedefDecl>(D)->setUnderlyingType(CurType);
2716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
273803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
2746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
275545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 0) {
2763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
2776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
2786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
2796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
2806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TagDecl *TD = dyn_cast<TagDecl>(d))
2810b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner    TD->addAttr(::new (S.Context) PackedAttr(1));
2826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
2836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // If the alignment is less than or equal to 8 bits, the packed attribute
2846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // has no effect.
2856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (!FD->getType()->isIncompleteType() &&
286803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner        S.Context.getTypeAlign(FD->getType()) <= 8)
287fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
28808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner        << Attr.getName() << FD->getType();
2896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    else
2900b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner      FD->addAttr(::new (S.Context) PackedAttr(1));
2916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else
2923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
2936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
2946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
29596329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenekstatic void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
29696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // check the attribute arguments.
29796329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  if (Attr.getNumArgs() > 0) {
2983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
29996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek    return;
30096329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  }
30196329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
30296329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // The IBOutlet attribute only applies to instance variables of Objective-C
30396329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  // classes.
304327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek  if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
3050b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner    d->addAttr(::new (S.Context) IBOutletAttr());
30696329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek  else
307327426076e1acc8217307cb236269ccf08c18fe6Ted Kremenek    S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
30896329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek}
30996329d4e07a9bcddb5a927892b70408c8fd8c474Ted Kremenek
310eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenekstatic void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
311eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // GCC ignores the nonnull attribute on K&R style function
312eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // prototypes, so we ignore it as well
313d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isFunctionOrMethod(d) || !hasFunctionProto(d)) {
314fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
3155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
316eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    return;
317eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
318eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
319d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
320eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
321eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  // The nonnull attribute only applies to pointers.
322eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  llvm::SmallVector<unsigned, 10> NonNullArgs;
323eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
324eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  for (AttributeList::arg_iterator I=Attr.arg_begin(),
325eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek                                   E=Attr.arg_end(); I!=E; ++I) {
326eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
327eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
328eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // The argument must be an integer constant expression.
329f5e883474796afd26e52a010cd9bf90374fa1915Ted Kremenek    Expr *Ex = static_cast<Expr *>(*I);
330eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    llvm::APSInt ArgNum(32);
331eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (!Ex->isIntegerConstantExpr(ArgNum, S.Context)) {
332fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
333fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
334eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
335eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
336eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
337eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    unsigned x = (unsigned) ArgNum.getZExtValue();
338eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
339eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    if (x < 1 || x > NumArgs) {
340fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
34130bc96544346bea42921cf6837e66cef80d664b4Chris Lattner       << "nonnull" << I.getArgNum() << Ex->getSourceRange();
342eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      return;
343eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
344465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek
345465172f304248a9aab6f2c398a836ce4e25efbbfTed Kremenek    --x;
346eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
347eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    // Is the function argument a pointer type?
34846bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    QualType T = getFunctionOrMethodArgType(d, x);
34946bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    if (!T->isPointerType() && !T->isBlockPointerType()) {
350eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek      // FIXME: Should also highlight argument in decl.
351fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
352fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "nonnull" << Ex->getSourceRange();
3537fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      continue;
354eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    }
355eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
356eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek    NonNullArgs.push_back(x);
357eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
358eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
3597fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // If no arguments were specified to __attribute__((nonnull)) then all
3607fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  // pointer arguments have a nonnull attribute.
3617fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  if (NonNullArgs.empty()) {
36246bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
36346bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      QualType T = getFunctionOrMethodArgType(d, I);
36446bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek      if (T->isPointerType() || T->isBlockPointerType())
365d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar        NonNullArgs.push_back(I);
36646bbacac37141ed9d01d5b6473e8211554b02710Ted Kremenek    }
3677fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3687fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    if (NonNullArgs.empty()) {
3697fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_no_pointers);
3707fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek      return;
3717fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek    }
372eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  }
3737fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek
3747fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned* start = &NonNullArgs[0];
3757fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  unsigned size = NonNullArgs.size();
3767fb43c17eb2b4102f40a80a355629aacd70589adTed Kremenek  std::sort(start, start + size);
3770b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) NonNullAttr(start, size));
378eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek}
379eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek
380803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
3816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
382545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
3833c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
3846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
387545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
3886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
3896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
3906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
392fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
3933c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "alias" << 1;
3946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
3956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
3966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
3976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *Alias = Str->getStrData();
3986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned AliasLen = Str->getByteLength();
3996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: check if target symbol exists in current file
4016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
4020b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
4036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
405af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbarstatic void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
406af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar                                   Sema &S) {
407af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  // check the attribute arguments.
408af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
4093c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
410af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    return;
411af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  }
4125bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
413c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
4145bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4155dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
4165bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
4175bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
418af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
4190b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) AlwaysInlineAttr());
420af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar}
421af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar
422b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
4235dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek                                     Sema &S) {
4246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
425545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
4263c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
427b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    return false;
4286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
429d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar
43019c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump  if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
43119c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    ValueDecl *VD = dyn_cast<ValueDecl>(d);
43219c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    if (VD == 0 || !VD->getType()->isBlockPointerType()) {
43319c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4345dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek        << Attr.getName() << 0 /*function*/;
43519c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump      return false;
43619c30c00e5e01e4608a43c7deb504f343f09e46dMike Stump    }
4376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
4386b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
439b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  return true;
440b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
441b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
442b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4435dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (HandleCommonNoReturnAttr(d, Attr, S))
444b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    d->addAttr(::new (S.Context) NoReturnAttr());
445b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek}
446b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek
447b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenekstatic void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
448b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek                                       Sema &S) {
4495dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (HandleCommonNoReturnAttr(d, Attr, S))
450b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
4516b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
4526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
45373798892751e378cbcdef43579c1d41685091fd0Ted Kremenekstatic void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
45473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  // check the attribute arguments.
45573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  if (Attr.getNumArgs() != 0) {
4563c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
45773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
45873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
45973798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
460d3f2c10f881311831a84114179342ff4db55e0c3Daniel Dunbar  if (!isa<VarDecl>(d) && !isFunctionOrMethod(d)) {
461fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4625dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
46373798892751e378cbcdef43579c1d41685091fd0Ted Kremenek    return;
46473798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  }
46573798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
4660b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) UnusedAttr());
46773798892751e378cbcdef43579c1d41685091fd0Ted Kremenek}
46873798892751e378cbcdef43579c1d41685091fd0Ted Kremenek
469b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbarstatic void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
470b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  // check the attribute arguments.
471b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (Attr.getNumArgs() != 0) {
472b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
473b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
474b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
475b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
476b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  if (const VarDecl *VD = dyn_cast<VarDecl>(d)) {
477186204bfcf9c53d48143ec300d4c3d036fed4140Daniel Dunbar    if (VD->hasLocalStorage() || VD->hasExternalStorage()) {
478b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
479b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar      return;
480b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    }
481b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  } else if (!isFunctionOrMethod(d)) {
482b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
4835dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
484b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar    return;
485b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  }
486b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
4870b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) UsedAttr());
488b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar}
489b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar
4903068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
4913068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
4923068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
493fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
494fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0 or 1";
4953068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
4963068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
4973068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
4983068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
4993068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
5003068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
5013068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
5023068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
503fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
5043c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "constructor" << 1 << E->getSourceRange();
5053068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5063068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5073068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5083068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5093068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
510c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
511fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5125dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
5133068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5143068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5153068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5160b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) ConstructorAttr(priority));
5173068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
5183068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5193068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbarstatic void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5203068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  // check the attribute arguments.
5213068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
522fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
523fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner       << "0 or 1";
5243068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5253068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5263068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5273068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  int priority = 65535; // FIXME: Do not hardcode such constants.
5283068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  if (Attr.getNumArgs() > 0) {
5293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    Expr *E = static_cast<Expr *>(Attr.getArg(0));
5303068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    llvm::APSInt Idx(32);
5313068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
532fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
5333c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "destructor" << 1 << E->getSourceRange();
5343068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar      return;
5353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    }
5363068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    priority = Idx.getZExtValue();
5373068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5383068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5396782fc6925a85c3772253e272745589a0c799c15Anders Carlsson  if (!isa<FunctionDecl>(d)) {
540fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
5415dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
5423068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    return;
5433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  }
5443068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
5450b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) DestructorAttr(priority));
5463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar}
5473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar
548803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5496b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
550545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
5513c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
5526b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5536b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5550b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) DeprecatedAttr());
5566b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
5576b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
558bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanianstatic void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
559bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  // check the attribute arguments.
560bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
561bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
562bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian    return;
563bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  }
564bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
5650b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) UnavailableAttr());
566bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian}
567bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian
568803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
5696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
570545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
5713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
5726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5736b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
575545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *Arg = static_cast<Expr*>(Attr.getArg(0));
5766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  Arg = Arg->IgnoreParenCasts();
5776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
5786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Str == 0 || Str->isWide()) {
580fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
5813c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "visibility" << 1;
5826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
5836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
5846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  const char *TypeStr = Str->getStrData();
5866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned TypeLen = Str->getByteLength();
5876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  VisibilityAttr::VisibilityTypes type;
5886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
5896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (TypeLen == 7 && !memcmp(TypeStr, "default", 7))
5906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::DefaultVisibility;
5916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6))
5926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility;
5936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8))
5946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::HiddenVisibility; // FIXME
5956b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9))
5966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    type = VisibilityAttr::ProtectedVisibility;
5976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  else {
59808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
5996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
6006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
6016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6020b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) VisibilityAttr(type));
6036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
6046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
6050db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
6060db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner                                    Sema &S) {
6070db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (Attr.getNumArgs() != 0) {
6080db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
6090db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6100db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
6110db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6120db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
6130db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (OCI == 0) {
6140db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
6150db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    return;
6160db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  }
6170db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6180b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) ObjCExceptionAttr());
6190db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner}
6200db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner
6210db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattnerstatic void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
622fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  if (Attr.getNumArgs() != 0) {
623fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
624fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    return;
625fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
6260db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
627fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    QualType T = TD->getUnderlyingType();
628fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    if (!T->isPointerType() ||
629fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian        !T->getAsPointerType()->getPointeeType()->isRecordType()) {
630fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
631fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian      return;
632fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian    }
633fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  }
6340b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
635fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian}
636fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian
637f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregorstatic void
638f9201e0ff1779567150b70856753d9f2c6a91467Douglas GregorHandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
639f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (Attr.getNumArgs() != 0) {
640f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
641f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
642f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
643f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
644f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  if (!isa<FunctionDecl>(D)) {
645f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
646f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor    return;
647f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  }
648f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
6490b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) OverloadableAttr());
650f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor}
651f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor
6529eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroffstatic void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
6539eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (!Attr.getParameterName()) {
654fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
6553c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << 1;
6569eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6579eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6589eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6599eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  if (Attr.getNumArgs() != 0) {
6603c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
6619eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6629eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6639eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6649eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  BlocksAttr::BlocksAttrTypes type;
66592e62b02226410bcad8584541b8f1ff4d35ebab9Chris Lattner  if (Attr.getParameterName()->isStr("byref"))
6669eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    type = BlocksAttr::ByRef;
6679eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  else {
668fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
6693c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "blocks" << Attr.getParameterName();
6709eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff    return;
6719eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  }
6729eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
6730b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) BlocksAttr(type));
6749eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff}
6759eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff
676770918281c5bdc7b5b3942285c407e3d62270053Anders Carlssonstatic void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
677770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  // check the attribute arguments.
678770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 2) {
679fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
680fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "0, 1 or 2";
681770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
682770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
684770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int sentinel = 0;
685770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 0) {
686770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(0));
687770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
688770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
689fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
6903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner       << "sentinel" << 1 << E->getSourceRange();
691770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
692770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
693770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    sentinel = Idx.getZExtValue();
694770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
695770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (sentinel < 0) {
696fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero)
697fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
698770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
699770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
700770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
701770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
702770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  int nullPos = 0;
703770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (Attr.getNumArgs() > 1) {
704770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    Expr *E = static_cast<Expr *>(Attr.getArg(1));
705770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    llvm::APSInt Idx(32);
706770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
707fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
7083c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner        << "sentinel" << 2 << E->getSourceRange();
709770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
710770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
711770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    nullPos = Idx.getZExtValue();
712770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
713770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (nullPos > 1 || nullPos < 0) {
714770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // FIXME: This error message could be improved, it would be nice
715770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      // to say what the bounds actually are.
716fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
717fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << E->getSourceRange();
718770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
719770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
720770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
721770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
722770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
723897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    const FunctionType *FT = FD->getType()->getAsFunctionType();
724897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    assert(FT && "FunctionDecl has non-function type?");
725897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner
726897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (isa<FunctionNoProtoType>(FT)) {
727897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_named_arguments);
728897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner      return;
729897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    }
730897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner
731897cd90fef4cd5139999585f3af31d85c2d07720Chris Lattner    if (!cast<FunctionProtoType>(FT)->isVariadic()) {
7323bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
733770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
734770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    }
735770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
736770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    if (!MD->isVariadic()) {
7373bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
738770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson      return;
7392f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
7402f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (isa<BlockDecl>(d)) {
7412f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    // Note! BlockDecl is typeless. Variadic diagnostics
7422f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    // will be issued by the caller.
7432f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    ;
7442f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian  } else if (const VarDecl *V = dyn_cast<VarDecl>(d)) {
7452f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    QualType Ty = V->getType();
746daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
747daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(d)
748daf0415583e33d5d279197c65e9227c1ed92474bFariborz Jahanian        : Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType();
7492f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      if (!cast<FunctionProtoType>(FT)->isVariadic()) {
7503bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        int m = Ty->isFunctionPointerType() ? 0 : 1;
7513bba33d6f58844d4924ab1e221dc2ff44c521624Fariborz Jahanian        S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
7522f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian        return;
7532f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      }
7542f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
7552f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    else {
7562f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
757ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
7582f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian      return;
7592f7c39246a968b921a6d95c7f8037fb3429e9501Fariborz Jahanian    }
760770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  } else {
761fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
762ffb0081d0c0509eb4884143381cb3e5a5f6947b4Fariborz Jahanian      << Attr.getName() << 6 /*function, method or block */;
763770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson    return;
764770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  }
76588f1ba0f0439e31ab57ffc088aa91137cadee585Fariborz Jahanian  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
766770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson}
767770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson
768026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
769026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // check the attribute arguments.
770026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (Attr.getNumArgs() != 0) {
771026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
772026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
773026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
774026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
775026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  // TODO: could also be applied to methods?
776026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
777026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (!Fn) {
778026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
7795dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
780026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    return;
781026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  }
782026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
7830b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
784026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
785026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
786026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
7876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
788545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
7893c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
7906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
7916b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
7926e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
7936e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // TODO: could also be applied to methods?
7946e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
7956e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
7965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
7976e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
7986e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
7996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8000b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) WeakAttr());
8016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
8036e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbarstatic void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8046e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // check the attribute arguments.
8056e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (Attr.getNumArgs() != 0) {
8066e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8076e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8086e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
8096e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
8106e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // weak_import only applies to variable & function declarations.
8116e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  bool isDef = false;
8126e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
8136e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    isDef = (!VD->hasExternalStorage() || VD->getInit());
8146e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8157297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor    isDef = FD->getBody(S.Context);
816d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian  } else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
817d4edddde6d3966ad4a4f60d9af0f9dd36995495cFariborz Jahanian    // We ignore weak import on properties and methods
8181c90f4dc686ab872013544664c797604a309c563Mike Stump    return;
8196e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  } else {
8206e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8215dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 2 /*variable and function*/;
8226e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8236e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
8246e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
8256e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  // Merge should handle any subsequent violations.
8266e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  if (isDef) {
8276e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    S.Diag(Attr.getLoc(),
8286e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar           diag::warn_attribute_weak_import_invalid_on_definition)
8296e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar      << "weak_import" << 2 /*variable and function*/;
8306e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar    return;
8316e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  }
8326e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
8336e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  D->addAttr(::new (S.Context) WeakImportAttr());
8346e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar}
8356e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar
836026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
838545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8393c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8427b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8432f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
844026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
8450b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner    D->addAttr(::new (S.Context) DLLImportAttr());
8462f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8472f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8482f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
849026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
8502f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
8512f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8525dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
8532f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8542f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8552f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
8562f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllimport attribute is ignored for inlined functions.
8572f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
8582f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
8592f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
8602f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8612f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8622f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
8632f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // The attribute is also overridden by a subsequent declaration as dllexport.
8642f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Warning is emitted.
8652f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  for (AttributeList *nextAttr = Attr.getNext(); nextAttr;
8662f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov       nextAttr = nextAttr->getNext()) {
8672f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    if (nextAttr->getKind() == AttributeList::AT_dllexport) {
8682f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
8692f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov      return;
8702f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    }
8712f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8722f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
873026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (D->getAttr<DLLExportAttr>()) {
8742f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
8752f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8762f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8772f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
8780b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) DLLImportAttr());
8796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
8806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
881026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
8826b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
883545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
8843c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
8856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
8866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
8877b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
8882f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Attribute can be applied only to functions or variables.
889026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  if (isa<VarDecl>(D)) {
8900b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner    D->addAttr(::new (S.Context) DLLExportAttr());
8912f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8922f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
8932f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
894026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
8952f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (!FD) {
8962f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
8975dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 2 /*variable and function*/;
8982f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
8992f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9002f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
9012f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // Currently, the dllexport attribute is ignored for inlined functions,
9022f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  // unless the -fkeep-inline-functions flag has been used. Warning is emitted;
9032f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  if (FD->isInline()) {
9042f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
9052f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
9062f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov    return;
9072f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov  }
9082f402708e62f89fb875442802e3d3f20fc909d33Anton Korobeynikov
9090b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) DLLExportAttr());
9106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
912026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattnerstatic void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
91317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Attribute has no arguments.
91417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (Attr.getNumArgs() != 1) {
91517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
91617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
91717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
91817f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
91917f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // Make sure that there is a string literal as the sections's single
92017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  // argument.
92117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  StringLiteral *SE =
92217f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    dyn_cast<StringLiteral>(static_cast<Expr *>(Attr.getArg(0)));
92317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  if (!SE) {
92417f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    // FIXME
92517f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
92617f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar    return;
92717f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  }
9280b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
9290b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner                                                     SE->getByteLength())));
93017f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar}
93117f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar
932803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9337b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
934545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
9353c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9376b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9387b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9397b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute can be applied only to functions.
9407b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
9417b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9425dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9437b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
9447b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
9457b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9467b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
9477b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<FastCallAttr>()) {
9487b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
9497b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "stdcall" << "fastcall";
9507b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
9517b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
9527b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9530b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) StdCallAttr());
9546b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9556b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
956803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9577b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // Attribute has no arguments.
958545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
9593c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9606b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9627b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9637b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (!isa<FunctionDecl>(d)) {
9647b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
9655dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
9667b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
9677b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
9687b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9697b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  // stdcall and fastcall attributes are mutually incompatible.
9707b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  if (d->getAttr<StdCallAttr>()) {
9717b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
9727b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov      << "fastcall" << "stdcall";
9737b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov    return;
9747b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov  }
9757b0a52f982e3514425fc8a3c8fc728f17c27c08eAnton Korobeynikov
9760b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) FastCallAttr());
9776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
979803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
9806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
981545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
9823c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
9836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
9846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
9856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
9860b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) NoThrowAttr());
9876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
9886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
989232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
990232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
991232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
9923c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
993232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
994232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
995232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
9960b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) ConstAttr());
997232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
998232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
999232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlssonstatic void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1000232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  // check the attribute arguments.
1001232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  if (Attr.getNumArgs() != 0) {
10023c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1003232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson    return;
1004232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  }
1005232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
10060b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) PureAttr());
1007232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson}
1008232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson
1009f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlssonstatic void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
101089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // Match gcc which ignores cleanup attrs when compiling C++.
101189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  if (S.getLangOptions().CPlusPlus)
101289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
101389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
1014f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!Attr.getParameterName()) {
1015f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1016f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1017f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1018f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1019f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (Attr.getNumArgs() != 0) {
1020f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1021f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1022f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1023f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1024f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  VarDecl *VD = dyn_cast<VarDecl>(d);
1025f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1026f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!VD || !VD->hasLocalStorage()) {
1027f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup";
1028f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1029f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1030f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1031f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  // Look up the function
103247b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor  NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
103347b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor                                        Sema::LookupOrdinaryName);
1034f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!CleanupDecl) {
103589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
1036f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1037f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1038f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1039f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1040f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  FunctionDecl *FD = dyn_cast<FunctionDecl>(CleanupDecl);
1041f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (!FD) {
104289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) <<
1043f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1044f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1045f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1046f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
1047f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  if (FD->getNumParams() != 1) {
104889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_must_take_one_arg) <<
1049f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson      Attr.getParameterName();
1050f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson    return;
1051f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  }
1052f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
105389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // We're currently more strict than GCC about what function types we accept.
105489941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  // If this ever proves to be a problem it should be easy to fix.
105589941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType Ty = S.Context.getPointerType(VD->getType());
105689941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  QualType ParamTy = FD->getParamDecl(0)->getType();
1057d5e3e8ec50d6ea481b3bc841dcbe853175d05122Eli Friedman  if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) {
105889941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    S.Diag(Attr.getLoc(),
105989941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson           diag::err_attribute_cleanup_func_arg_incompatible_type) <<
106089941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson      Attr.getParameterName() << ParamTy << Ty;
106189941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson    return;
106289941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson  }
106389941c1c68d8e4eec3c8ea8ee68e34d9e3c7b083Anders Carlsson
10640b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) CleanupAttr(FD));
1065f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson}
1066f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson
10676b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// Handle __attribute__((format(type,idx,firstarg))) attributes
10686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
1069803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
10706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1071545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (!Attr.getParameterName()) {
1072fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
10733c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 1;
10746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10766b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1077545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 2) {
10783c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 3;
10796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1082620d89ca4eb5dcb6be13a42aafa4849eaa9b834bFariborz Jahanian  if (!isFunctionOrMethodOrBlock(d) || !hasFunctionProto(d)) {
1083fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
10845dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
10856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
10866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
10876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: in C++ the implicit 'this' function parameter also counts.
10896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // this is needed in order to be compatible with GCC
10906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // the index must start in 1 and the limit is numargs+1
10913568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
10926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned FirstIdx = 1;
10936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1094545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  const char *Format = Attr.getParameterName()->getName();
1095545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  unsigned FormatLen = Attr.getParameterName()->getLength();
10966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
10976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Normalize the argument, __foo__ becomes foo.
10986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' &&
10996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') {
11006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Format += 2;
11016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    FormatLen -= 4;
11026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool Supported = false;
11056b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_NSString = false;
11066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  bool is_strftime = false;
1107085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  bool is_CFString = false;
11086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  switch (FormatLen) {
11106b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  default: break;
1111803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 5: Supported = !memcmp(Format, "scanf", 5); break;
1112803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 6: Supported = !memcmp(Format, "printf", 6); break;
1113803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case 7: Supported = !memcmp(Format, "strfmon", 7); break;
11146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  case 8:
1115085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
1116085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_NSString = !memcmp(Format, "NSString", 8)) ||
1117085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar                (is_CFString = !memcmp(Format, "CFString", 8));
11186b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    break;
11196b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11206b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11216b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!Supported) {
1122fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
1123fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "format" << Attr.getParameterName()->getName();
11246b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11266b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11276b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // checks for the 2nd argument
1128545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *IdxExpr = static_cast<Expr *>(Attr.getArg(0));
1129803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt Idx(32);
1130803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
1131fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11323c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
11336b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11346b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11356b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11366b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
1137fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
11383c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 2 << IdxExpr->getSourceRange();
11396b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11406b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11416b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11426b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // FIXME: Do we need to bounds check?
11436b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned ArgIdx = Idx.getZExtValue() - 1;
11446b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11456b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // make sure the format string is really a string
11463568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
11476b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1148085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  if (is_CFString) {
1149085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    if (!isCFStringType(Ty, S.Context)) {
1150fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1151fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "a CFString" << IdxExpr->getSourceRange();
1152085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar      return;
1153085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar    }
1154085e8f7da37a227ceee7f98b724e0a42e04d01caDaniel Dunbar  } else if (is_NSString) {
1155390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: do we need to check if the type is NSString*?  What are the
1156390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // semantics?
1157803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    if (!isNSStringType(Ty, S.Context)) {
1158390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump      // FIXME: Should highlight the actual expression that has the wrong type.
1159fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1160fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << "an NSString" << IdxExpr->getSourceRange();
11616b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
11626b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
11636b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (!Ty->isPointerType() ||
11646b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner             !Ty->getAsPointerType()->getPointeeType()->isCharType()) {
1165390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump    // FIXME: Should highlight the actual expression that has the wrong type.
1166fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_format_attribute_not)
1167fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "a string type" << IdxExpr->getSourceRange();
11686b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11696b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11706b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11716b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the 3rd argument
1172545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *FirstArgExpr = static_cast<Expr *>(Attr.getArg(1));
1173803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  llvm::APSInt FirstArg(32);
1174803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
1175fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int)
11763c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
11776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
11786b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11796b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check if the function is variadic if the 3rd argument non-zero
11816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (FirstArg != 0) {
11823568249c2d72d58b835a22d9186f5a6b4fc4bcd6Daniel Dunbar    if (isFunctionOrMethodVariadic(d)) {
11836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      ++NumArgs; // +1 for ...
11846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    } else {
1185803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner      S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);
11866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
11876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
11886b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
11896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
11903c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // strftime requires FirstArg to be 0 because it doesn't read from any
11913c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner  // variable the input is just the current time + the format string.
11926b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (is_strftime) {
11936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    if (FirstArg != 0) {
1194fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      S.Diag(Attr.getLoc(), diag::err_format_strftime_third_parameter)
1195fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner        << FirstArgExpr->getSourceRange();
11966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner      return;
11976b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    }
11986b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // if 0 it disables parameter checking (to use with e.g. va_list)
11996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  } else if (FirstArg != 0 && FirstArg != NumArgs) {
1200fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
12013c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner      << "format" << 3 << FirstArgExpr->getSourceRange();
12026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12036b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12050b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
12066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner                            Idx.getZExtValue(), FirstArg.getZExtValue()));
12076b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12090b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
12100b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner                                       Sema &S) {
12116b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1212545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 0) {
12133c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
12146b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12156b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12166b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12170c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  // Try to find the underlying union declaration.
12180c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl *RD = 0;
1219bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  TypedefDecl *TD = dyn_cast<TypedefDecl>(d);
12200c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (TD && TD->getUnderlyingType()->isUnionType())
12210c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
12220c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  else
12230c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    RD = dyn_cast<RecordDecl>(d);
12240c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
12250c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD || !RD->isUnion()) {
1226fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
12275dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 1 /*union*/;
12286b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12296b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12306b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12310c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (!RD->isDefinition()) {
12320c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(),
12330c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        diag::warn_transparent_union_attribute_not_definition);
12340c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
12350c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
12360c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor
12370c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RecordDecl::field_iterator Field = RD->field_begin(S.Context),
12380c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                          FieldEnd = RD->field_end(S.Context);
12390c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (Field == FieldEnd) {
12400c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
12410c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
12420c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1243bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
12440c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  FieldDecl *FirstField = *Field;
12450c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  QualType FirstType = FirstField->getType();
12460c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  if (FirstType->isFloatingType() || FirstType->isVectorType()) {
12470c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    S.Diag(FirstField->getLocation(),
12480c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor           diag::warn_transparent_union_attribute_floating);
12490c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    return;
12500c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  }
1251bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman
12520c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstSize = S.Context.getTypeSize(FirstType);
12530c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
12540c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  for (; Field != FieldEnd; ++Field) {
12550c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    QualType FieldType = Field->getType();
12560c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor    if (S.Context.getTypeSize(FieldType) != FirstSize ||
12570c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        S.Context.getTypeAlign(FieldType) != FirstAlign) {
12580c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      // Warn if we drop the attribute.
12590c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
12600c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
12610c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor                                 : S.Context.getTypeAlign(FieldType);
12620c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      S.Diag(Field->getLocation(),
12630c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor          diag::warn_transparent_union_attribute_field_size_align)
12640c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << Field->getDeclName() << FieldBits;
12650c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      unsigned FirstBits = isSize? FirstSize : FirstAlign;
12660c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor      S.Diag(FirstField->getLocation(),
12670c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor             diag::note_transparent_union_first_field_size_align)
12680c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor        << isSize << FirstBits;
1269bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman      return;
1270bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman    }
1271bc88745b43f440341e60ed93b0d27bac7c418029Eli Friedman  }
12726b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12730c74e8a4e8865ec9ebb8efc0af247a3c077236c4Douglas Gregor  RD->addAttr(::new (S.Context) TransparentUnionAttr());
12746b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12756b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12760b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12776b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1278545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() != 1) {
12793c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12806b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12816b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
1282545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  Expr *argExpr = static_cast<Expr *>(Attr.getArg(0));
12836b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  StringLiteral *SE = dyn_cast<StringLiteral>(argExpr);
12846b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
12856b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // Make sure that there is a string literal as the annotation's single
12866b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // argument.
12876b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  if (!SE) {
12880b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
12896b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
12906b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
12910b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
12920b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner                                                        SE->getByteLength())));
12936b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
12946b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
1295803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
12966b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  // check the attribute arguments.
1297545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() > 1) {
12983c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
12996b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13006b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
13016b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner
13026b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  unsigned Align = 0;
1303545dd3401e7f31c256d69cb948a45d5ca781064cChris Lattner  if (Attr.getNumArgs() == 0) {
13046b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    // FIXME: This should be the target specific maximum alignment.
13057549c5589ac0d2087e55f2bdd4854adef23f29fdDaniel Dunbar    // (For now we just use 128 bits which is the maximum on X86).
13066b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    Align = 128;
13070b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner    d->addAttr(::new (S.Context) AlignedAttr(Align));
13086b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner    return;
13096b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner  }
131049e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner
131149e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0));
131249e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  llvm::APSInt Alignment(32);
1313803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  if (!alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) {
1314fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
1315fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "aligned" << alignmentExpr->getSourceRange();
131649e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner    return;
131749e2d34f74f98bef23e37c415ce90cd783cdea24Chris Lattner  }
1318396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
1319396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two)
1320396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar      << alignmentExpr->getSourceRange();
1321396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar    return;
1322396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar  }
1323396b2a22788b0134018760d6a476de1e20f81334Daniel Dunbar
13240b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
13256b6b5372f4b60b1c5ee101709e71a04642c835f4Chris Lattner}
1326fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
13270b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner/// HandleModeAttr - This attribute modifies the width of a decl with
1328065c5a801f46dda8ff0cd6ad954c4e5f94a3be75Chris Lattner/// primitive type.
1329fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
1330fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// Despite what would be logical, the mode attribute is a decl attribute,
1331fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make
1332fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner/// 'G' be HImode, not an intermediate pointer.
1333fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner///
13340b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattnerstatic void HandleModeAttr(Decl *D, const AttributeList &Attr, Sema &S) {
1335fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // This attribute isn't documented, but glibc uses it.  It changes
1336fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // the width of an int or unsigned int to the specified size.
1337fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1338fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Check that there aren't any arguments
1339fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Attr.getNumArgs() != 0) {
13403c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1341fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1342fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1343fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1344fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  IdentifierInfo *Name = Attr.getParameterName();
1345fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (!Name) {
13460b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_missing_parameter_name);
1347fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1348fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1349fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  const char *Str = Name->getName();
1350fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned Len = Name->getLength();
1351fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1352fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Normalize the attribute name, __foo__ becomes foo.
1353fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (Len > 4 && Str[0] == '_' && Str[1] == '_' &&
1354fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner      Str[Len - 2] == '_' && Str[Len - 1] == '_') {
1355fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Str += 2;
1356fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    Len -= 4;
1357fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1358fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1359fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  unsigned DestWidth = 0;
1360fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  bool IntegerMode = true;
136173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  bool ComplexMode = false;
1362fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (Len) {
1363fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 2:
136473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    switch (Str[0]) {
136573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'Q': DestWidth = 8; break;
136673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'H': DestWidth = 16; break;
136773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'S': DestWidth = 32; break;
136873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'D': DestWidth = 64; break;
136973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'X': DestWidth = 96; break;
137073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    case 'T': DestWidth = 128; break;
137173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
137273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (Str[1] == 'F') {
137373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
137473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] == 'C') {
137573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      IntegerMode = false;
137673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      ComplexMode = true;
137773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    } else if (Str[1] != 'I') {
137873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      DestWidth = 0;
137973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1380fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1381fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 4:
1382fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // FIXME: glibc uses 'word' to define register_t; this is narrower than a
1383fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    // pointer on PIC16 and other embedded platforms.
1384fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "word", 4))
13850b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1386fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "byte", 4))
13870b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getCharWidth();
1388fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1389fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 7:
1390fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!memcmp(Str, "pointer", 7))
13910b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      DestWidth = S.Context.Target.getPointerWidth(0);
1392fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1393fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1394fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1395fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType OldTy;
1396fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1397fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = TD->getUnderlyingType();
1398fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
1399fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    OldTy = VD->getType();
1400fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else {
1401fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner    S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
1402fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner      << "mode" << SourceRange(Attr.getLoc(), Attr.getLoc());
1403fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1404fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
140573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
140673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (!OldTy->getAsBuiltinType() && !OldTy->isComplexType())
140773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    S.Diag(Attr.getLoc(), diag::err_mode_not_primitive);
140873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  else if (IntegerMode) {
140973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isIntegralType())
141073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
141173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else if (ComplexMode) {
141273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isComplexType())
141373397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
141473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  } else {
141573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!OldTy->isFloatingType())
141673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_mode_wrong_type);
141773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  }
141873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman
1419390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
1420390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // and friends, at least with glibc.
1421390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // FIXME: Make sure 32/64-bit integers don't get defined to types of the wrong
1422390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump  // width on unusual platforms.
1423f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Make sure floating-point mappings are accurate
1424f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  // FIXME: Support XF and TF types
1425fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  QualType NewTy;
1426fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  switch (DestWidth) {
1427fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 0:
14283c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
1429fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1430fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  default:
14313c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1432fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    return;
1433fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 8:
143473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
143573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
143673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
143773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1438fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
14390b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.SignedCharTy;
1440fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
14410b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedCharTy;
1442fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1443fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 16:
144473397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    if (!IntegerMode) {
144573397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
144673397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman      return;
144773397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    }
1448fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (OldTy->isSignedIntegerType())
14490b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.ShortTy;
1450fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
14510b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedShortTy;
1452fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1453fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 32:
1454fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
14550b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.FloatTy;
1456fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
14570b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.IntTy;
1458fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
14590b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedIntTy;
1460fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
1461fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  case 64:
1462fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    if (!IntegerMode)
14630b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.DoubleTy;
1464fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else if (OldTy->isSignedIntegerType())
14650b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.LongLongTy;
1466fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    else
14670b2f4da7651feb6edab5e4a657fce058f0dd514aChris Lattner      NewTy = S.Context.UnsignedLongLongTy;
1468fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    break;
146973397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  case 96:
147073397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.LongDoubleTy;
147173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1472f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman  case 128:
1473f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    if (!IntegerMode) {
1474f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
1475f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman      return;
1476f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    }
1477f98aba35e6c3da5aae61843fc01334939e4e12ecEli Friedman    NewTy = S.Context.getFixedWidthIntType(128, OldTy->isSignedIntegerType());
147873397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    break;
1479fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1480fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
148173397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman  if (ComplexMode) {
148273397496fec250f565f49e27f8ba79f94f4e7427Eli Friedman    NewTy = S.Context.getComplexType(NewTy);
1483fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  }
1484fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner
1485fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  // Install the new type.
1486fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D))
1487fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    TD->setUnderlyingType(NewTy);
1488fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner  else
1489fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner    cast<ValueDecl>(D)->setType(NewTy);
1490fbf1347e1e225cbc206563bba3f0a75f9ceaa571Chris Lattner}
14910744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1492d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlssonstatic void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1493d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  // check the attribute arguments.
1494d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  if (Attr.getNumArgs() > 0) {
1495d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
1496d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1497d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1498e896d98548b02223c7740d807a0aa6e20fba7079Anders Carlsson
14995bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (!isFunctionOrMethod(d)) {
1500d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15015dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
1502d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    return;
1503d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  }
1504d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
15050b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) NodebugAttr());
1506d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson}
1507d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson
15085bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlssonstatic void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
15095bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  // check the attribute arguments.
15105bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  if (Attr.getNumArgs() != 0) {
15115bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
15125bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
15135bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
15145bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
1515c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!isa<FunctionDecl>(d)) {
15165bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15175dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
15185bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson    return;
15195bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  }
15205bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
15210b2b6e1cb1573bb295c0a65813dc4df8d57f305bChris Lattner  d->addAttr(::new (S.Context) NoinlineAttr());
15225bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson}
15235bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson
1524cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattnerstatic void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
152526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  // check the attribute arguments.
152626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  if (Attr.getNumArgs() != 0) {
152726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
152826e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
152926e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
153026e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1531c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
1532c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (Fn == 0) {
153326e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15345dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName() << 0 /*function*/;
153526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner    return;
153626e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner  }
153726e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1538c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  if (!Fn->isInline()) {
1539cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner    S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
1540c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner    return;
1541c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner  }
1542c51974328b3a378c3c40b1fa527ecb928ed2bfdaChris Lattner
15439f9bf258f8ebae30bfb70feb9d797d6eb67b0460Douglas Gregor  d->addAttr(::new (S.Context) GNUInlineAttr());
154426e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner}
154526e25545b26ec06f5d674dbae00fb168e6688d90Chris Lattner
1546ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanianstatic void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
1547ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  // check the attribute arguments.
1548ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (Attr.getNumArgs() != 1) {
154955d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
1550ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1551ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
155255d3aaf9a537888734762170823daf750ea9036dEli Friedman
1553ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  if (!isFunctionOrMethod(d)) {
1554ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15555dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    << Attr.getName() << 0 /*function*/;
1556ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian    return;
1557ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian  }
155855d3aaf9a537888734762170823daf750ea9036dEli Friedman
155955d3aaf9a537888734762170823daf750ea9036dEli Friedman  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
156055d3aaf9a537888734762170823daf750ea9036dEli Friedman  llvm::APSInt NumParams(32);
156155d3aaf9a537888734762170823daf750ea9036dEli Friedman  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
156255d3aaf9a537888734762170823daf750ea9036dEli Friedman    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
156355d3aaf9a537888734762170823daf750ea9036dEli Friedman      << "regparm" << NumParamsExpr->getSourceRange();
156455d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
156555d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
156655d3aaf9a537888734762170823daf750ea9036dEli Friedman
1567264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov  if (S.Context.Target.getRegParmMax() == 0) {
1568264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_wrong_platform)
156955d3aaf9a537888734762170823daf750ea9036dEli Friedman      << NumParamsExpr->getSourceRange();
157055d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
157155d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
157255d3aaf9a537888734762170823daf750ea9036dEli Friedman
1573348f28ab6a574df6501ff8b76f9fc6753c155badAnton Korobeynikov  if (NumParams.getLimitedValue(255) > S.Context.Target.getRegParmMax()) {
1574264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov    S.Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
1575264a76cdf382c507f4d43e64c89f1503f003ac95Anton Korobeynikov      << S.Context.Target.getRegParmMax() << NumParamsExpr->getSourceRange();
157655d3aaf9a537888734762170823daf750ea9036dEli Friedman    return;
157755d3aaf9a537888734762170823daf750ea9036dEli Friedman  }
157855d3aaf9a537888734762170823daf750ea9036dEli Friedman
157955d3aaf9a537888734762170823daf750ea9036dEli Friedman  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
1580ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian}
1581ee760330a415635369556796a97afcfd6207f4dcFariborz Jahanian
15820744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
1583b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek// Checker-specific attribute handlers.
1584b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
1585b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1586b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenekstatic void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
1587b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek                                        Sema &S) {
1588b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
15895dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  QualType RetTy;
15905dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek
15915dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
15925dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = MD->getResultType();
15935dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d))
15945dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    RetTy = FD->getResultType();
15955dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  else {
15965dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
15975dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek        << Attr.getName() << 3 /* function or method */;
1598b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    return;
1599b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  }
1600b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
16015dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  if (!(S.Context.isObjCNSObjectType(RetTy) || RetTy->getAsPointerType())) {
16025dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
16035dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek      << Attr.getName();
16045dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek    return;
16055dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek  }
16065dc53c9c2328b5bea5422005b04960c18afd83adTed Kremenek
1607b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  switch (Attr.getKind()) {
1608b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    default:
1609b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      assert(0 && "invalid ownership attribute");
1610b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1611b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_cf_returns_retained:
1612b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
1613b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1614b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    case AttributeList::AT_ns_returns_retained:
1615b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
1616b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek      return;
1617b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  };
1618b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek}
1619b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1620b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek//===----------------------------------------------------------------------===//
16210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner// Top Level Sema Entry Points
16220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner//===----------------------------------------------------------------------===//
16230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
1624a89d82c1c819d17042ec2db4283326a850229b21Sebastian Redl/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
1625803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// the attribute applies to decls.  If the attribute is a type attribute, just
1626803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// silently ignore it.
1627803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnerstatic void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
1628803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  switch (Attr.getKind()) {
16293068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_IBOutlet:    HandleIBOutletAttr  (D, Attr, S); break;
1630803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_address_space:
1631ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian  case AttributeList::AT_objc_gc:
1632ba372b85524f712e5b97a176f6ce0197d365835dFariborz Jahanian    // Ignore these, these are type attributes, handled by ProcessTypeAttributes.
1633803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1634803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_alias:       HandleAliasAttr     (D, Attr, S); break;
16353068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_aligned:     HandleAlignedAttr   (D, Attr, S); break;
1636af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar  case AttributeList::AT_always_inline:
1637af668b0e7d3581dea3b4f29a9262686e83887e5bDaniel Dunbar    HandleAlwaysInlineAttr  (D, Attr, S); break;
1638b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek  case AttributeList::AT_analyzer_noreturn:
1639b725232b46e92f3e36b03a32a6fc75748c312122Ted Kremenek    HandleAnalyzerNoReturnAttr  (D, Attr, S); break;
16403068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_annotate:    HandleAnnotateAttr  (D, Attr, S); break;
16413068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
1642803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_deprecated:  HandleDeprecatedAttr(D, Attr, S); break;
16433068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_destructor:  HandleDestructorAttr(D, Attr, S); break;
1644803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_dllexport:   HandleDLLExportAttr (D, Attr, S); break;
16453068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_dllimport:   HandleDLLImportAttr (D, Attr, S); break;
16463068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_ext_vector_type:
16473068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    HandleExtVectorTypeAttr(D, Attr, S);
16483068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar    break;
1649803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_fastcall:    HandleFastCallAttr  (D, Attr, S); break;
1650803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_format:      HandleFormatAttr    (D, Attr, S); break;
1651cf2a7211b4785068c7efa836baab90b198a4d2a6Chris Lattner  case AttributeList::AT_gnu_inline:  HandleGNUInlineAttr(D, Attr, S); break;
16523068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_mode:        HandleModeAttr      (D, Attr, S); break;
1653eb2b2a3f1898f146c6e153a64ec58ec5e1750bd2Ted Kremenek  case AttributeList::AT_nonnull:     HandleNonNullAttr   (D, Attr, S); break;
16543068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_noreturn:    HandleNoReturnAttr  (D, Attr, S); break;
16553068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_nothrow:     HandleNothrowAttr   (D, Attr, S); break;
1656b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
1657b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  // Checker-specific.
1658b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_ns_returns_retained:
1659b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek  case AttributeList::AT_cf_returns_retained:
1660b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek    HandleNSReturnsRetainedAttr(D, Attr, S); break;
1661b71368d28532908ae1c2dc23f91761781205b3d0Ted Kremenek
16623068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_packed:      HandlePackedAttr    (D, Attr, S); break;
166317f194f4393a67fd28ad822c06d32b8cb99bad3fDaniel Dunbar  case AttributeList::AT_section:     HandleSectionAttr   (D, Attr, S); break;
16643068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_stdcall:     HandleStdCallAttr   (D, Attr, S); break;
1665bc1c877fe28fb6a825f0b226a0a2da99e713ea03Fariborz Jahanian  case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
166673798892751e378cbcdef43579c1d41685091fd0Ted Kremenek  case AttributeList::AT_unused:      HandleUnusedAttr    (D, Attr, S); break;
1667b805dad4aa386aeae0f72512895bd238678d37a5Daniel Dunbar  case AttributeList::AT_used:        HandleUsedAttr      (D, Attr, S); break;
16683068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
16693068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_visibility:  HandleVisibilityAttr(D, Attr, S); break;
1670026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner  case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
1671026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner    break;
16723068ae0feb5d477477f45045f7ec9d0414fe57f3Daniel Dunbar  case AttributeList::AT_weak:        HandleWeakAttr      (D, Attr, S); break;
16736e775dbafba2ab6634decc489eb3b4301b4b506bDaniel Dunbar  case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
1674803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  case AttributeList::AT_transparent_union:
1675803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    HandleTransparentUnionAttr(D, Attr, S);
1676803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
16770db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner  case AttributeList::AT_objc_exception:
16780db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    HandleObjCExceptionAttr(D, Attr, S);
16790db29ece81d360dcefbe912339c34abe5917f6a9Chris Lattner    break;
1680f9201e0ff1779567150b70856753d9f2c6a91467Douglas Gregor  case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
1681fa23c1d9adc99c662c1c0e192817185809d95614Fariborz Jahanian  case AttributeList::AT_nsobject:    HandleObjCNSObject  (D, Attr, S); break;
16829eae5761c0691c0f11d7a823b8ee54f05786cbbeSteve Naroff  case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
1683770918281c5bdc7b5b3942285c407e3d62270053Anders Carlsson  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
1684232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_const:       HandleConstAttr     (D, Attr, S); break;
1685232eb7d33b96ad8f99de3b5ae840421b3a7c6cb7Anders Carlsson  case AttributeList::AT_pure:        HandlePureAttr      (D, Attr, S); break;
1686f6e35d0b9f1e9f1b4c5d3ef924415fa5e7c89849Anders Carlsson  case AttributeList::AT_cleanup:     HandleCleanupAttr   (D, Attr, S); break;
1687d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson  case AttributeList::AT_nodebug:     HandleNodebugAttr   (D, Attr, S); break;
16885bab788d40026ad6e932a3cd9b86bc13f8a27661Anders Carlsson  case AttributeList::AT_noinline:    HandleNoinlineAttr  (D, Attr, S); break;
168955d3aaf9a537888734762170823daf750ea9036dEli Friedman  case AttributeList::AT_regparm:     HandleRegparmAttr   (D, Attr, S); break;
169005f8e471aae971c9867dbac148eba1275a570814Anders Carlsson  case AttributeList::IgnoredAttribute:
16915e204486a7dd1e5f7e14e941a2c7e707a8ad1a3bChris Lattner  case AttributeList::AT_no_instrument_function:  // Interacts with -pg.
169205f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    // Just ignore
169305f8e471aae971c9867dbac148eba1275a570814Anders Carlsson    break;
1694803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  default:
1695d87df37e0adaba0d5e33da7b1a14d7f1d94c5eefAnders Carlsson    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
1696803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    break;
1697803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1698803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1699803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
1700803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// ProcessDeclAttributeList - Apply all the decl attributes in the specified
1701803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner/// attribute list to the specified decl, ignoring any type attributes.
1702803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattnervoid Sema::ProcessDeclAttributeList(Decl *D, const AttributeList *AttrList) {
1703803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  while (AttrList) {
1704803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    ProcessDeclAttribute(D, *AttrList, *this);
1705803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner    AttrList = AttrList->getNext();
1706803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner  }
1707803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner}
1708803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
17090744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
17100744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// it, apply them to D.  This is a bit tricky because PD can have attributes
17110744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner/// specified in many different places, and we need to find and apply them all.
17120744e5f3325e2d2107506002e43c37ea0155a5acChris Lattnervoid Sema::ProcessDeclAttributes(Decl *D, const Declarator &PD) {
17130744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Apply decl attributes from the DeclSpec if present.
17140744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
17150744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
1716803d08039c5194cf51071ed1d8fbc5b18b3ec38bChris Lattner
17170744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Walk the declarator structure, applying decl attributes that were in a type
17180744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // position to the decl itself.  This handles cases like:
17190744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  //   int *__attr__(x)** D;
17200744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // when X is a decl attribute.
17210744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
17220744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    if (const AttributeList *Attrs = PD.getTypeObject(i).getAttrs())
17230744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner      ProcessDeclAttributeList(D, Attrs);
17240744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner
17250744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  // Finally, apply any attributes on the decl itself.
17260744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner  if (const AttributeList *Attrs = PD.getAttributes())
17270744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner    ProcessDeclAttributeList(D, Attrs);
17280744e5f3325e2d2107506002e43c37ea0155a5acChris Lattner}
1729